Board index » delphi » Recursing in Delphi 1?

Recursing in Delphi 1?

I'm trying to run the following function in Delphi 1:

procedure TForm1.GetFileList(SR : TSearchRec);
Var
   Found : Integer;
begin
   Found := 0;
   while Found = 0 do
   Begin
      if ((sr.Attr and faDirectory) > 0) and
         (sr.Name <> '.') and
         (sr.Name <> '..') then
      Begin
         GetFileList(Sr);              { Error occurs here}
      end
      else
      Begin
         if FileExists(Path.Text + '\' + sr.Name) then
            ListBox1.Items.Add(Path.Text+'\'+sr.Name);
      end;
      Found := FindNext(sr);
      Application.ProcessMessages;
   end;
   FindClose(sr);
end;

The function is suppose to fill a ListBox with the entire contents of a
specified drive/path.  What happens is this;  First time through, it
retrieves a file called "LASTDISK", which doesn't exist on the floppy disk
at all???

Second time through, it retrieves a directory name called "CIVILWAR", which
DOES exist, so, it tries to recurse so it can get the file names and add
them to the list.  But, as soon as it hits the "GetFileList" line marked
above, it blows up with a "Runtime error 202 at 001:01EA".  Any idea what
this is?  Is Recursion supported in Delphi 1?  If not, is there an
alternative to what I am trying to do?

Thanks,
Jesse

 

Re:Recursing in Delphi 1?


On Tue, 7 Jul 1998 18:31:07 -0400, "Jesse Castleberry"

Quote
<D...@iThink.net> wrote:
>I'm trying to run the following function in Delphi 1:

>procedure TForm1.GetFileList(SR : TSearchRec);
>Var
>   Found : Integer;
>begin
>   Found := 0;
>   while Found = 0 do
>   Begin
>      if ((sr.Attr and faDirectory) > 0) and
>         (sr.Name <> '.') and
>         (sr.Name <> '..') then
>      Begin
>         GetFileList(Sr);              { Error occurs here}
>      end
>      else
>      Begin
>         if FileExists(Path.Text + '\' + sr.Name) then
>            ListBox1.Items.Add(Path.Text+'\'+sr.Name);
>      end;
>      Found := FindNext(sr);
>      Application.ProcessMessages;
>   end;
>   FindClose(sr);
>end;

>The function is suppose to fill a ListBox with the entire contents of a
>specified drive/path.  What happens is this;  First time through, it
>retrieves a file called "LASTDISK", which doesn't exist on the floppy disk
>at all???

Oh yes it does. It is almost certainly the volume label  (which is
stored as a 'file' with attribute faVolumeID). Your code can check for
this to skip it.

Quote
>Second time through, it retrieves a directory name called "CIVILWAR", which
>DOES exist, so, it tries to recurse so it can get the file names and add
>them to the list.  But, as soon as it hits the "GetFileList" line marked
>above, it blows up with a "Runtime error 202 at 001:01EA".  Any idea what
>this is?  Is Recursion supported in Delphi 1?  If not, is there an
>alternative to what I am trying to do?

Well, what happens is, once you call GetFileList recursively, it will
then start GetFileList, get straight to the point where it calls
GetFileList recursively, then start GetFileList, etc. In other words,
you get an infinite recursion which is probably not what you want.
RTE 202 is, not surprisingly, 'stack overflow' (loosely meaning: too
many functions have been called without returning)

How to program this right ?
You write the GetFileList with a parameter 'mask', e.g.  (leaving out
details):

procedure GetFileList(mask: string);
var
    SR: TSearchRec;
begin
{...}
found := findfirst(mask,faAnyFile, SR);
while found = 0 do
begin
   { check if directory or invalid}
   if (it is a directory)
    then
       begin
             GetFileList([root] + SR.Name + '\' + '*.*');
       end
    else {process the file }
   found := findnext(sr);
end;
end;

e.g.
(bottom level call)
GetFileList('A:\*.*')
[root] is the directory part of the mask parameter, there are some
functions to help retrieve this in Delphi 1 (forgot the names). Note
that the SearchRec must be a local variable in the GetFileList
procedure, since each directory must have it's own SearchRec
(FindFirst and FindNext save some status information to SR that is
needed for the next call to FindNext)

This way it should work without much of a problem.

Hope you can figure it out from this.

David

Quote

>Thanks,
>Jesse

------------------
David A. Schweizer

iec ProGAMMA, The Netherlands
d.a.schweizer[OK, i don't want any more spam]gamma.rug.nl
guess where the '@' goes ?

Re:Recursing in Delphi 1?


'LASTDISK' is probably the volume name. You'll have to exclude out the
attribute faVolumeID ($08). Error 202 is a stack overflow. Your getting it
because you keep recursively calling GetFileList for the '.' directory. Don't
recursively call GetFileList if the faVolumeID attribute is set, or if the
directory starts with '.'.

Hope this helps,

Michel
--------
http://www.cam.org/~mibra/spider
Spider Object Database
Spider Container and Persistent Classes  (freeware)
WordShare string localization  (freeware)

Quote
Jesse Castleberry wrote:
> I'm trying to run the following function in Delphi 1:

> procedure TForm1.GetFileList(SR : TSearchRec);
> Var
>    Found : Integer;
> begin
>    Found := 0;
>    while Found = 0 do
>    Begin
>       if ((sr.Attr and faDirectory) > 0) and
>          (sr.Name <> '.') and
>          (sr.Name <> '..') then
>       Begin
>          GetFileList(Sr);              { Error occurs here}
>       end
>       else
>       Begin
>          if FileExists(Path.Text + '\' + sr.Name) then
>             ListBox1.Items.Add(Path.Text+'\'+sr.Name);
>       end;
>       Found := FindNext(sr);
>       Application.ProcessMessages;
>    end;
>    FindClose(sr);
> end;

> The function is suppose to fill a ListBox with the entire contents of a
> specified drive/path.  What happens is this;  First time through, it
> retrieves a file called "LASTDISK", which doesn't exist on the floppy disk
> at all???

> Second time through, it retrieves a directory name called "CIVILWAR", which
> DOES exist, so, it tries to recurse so it can get the file names and add
> them to the list.  But, as soon as it hits the "GetFileList" line marked
> above, it blows up with a "Runtime error 202 at 001:01EA".  Any idea what
> this is?  Is Recursion supported in Delphi 1?  If not, is there an
> alternative to what I am trying to do?

> Thanks,
> Jesse

Re:Recursing in Delphi 1?


In article <6nui9k$aa...@news2.ispnews.com>,
  "Jesse Castleberry" <D...@iThink.net> wrote:

Quote
> I'm trying to run the following function in Delphi 1:

> procedure TForm1.GetFileList(SR : TSearchRec);
> Var
>    Found : Integer;
> begin
>    Found := 0;
>    while Found = 0 do
>    Begin
>       if ((sr.Attr and faDirectory) > 0) and
>          (sr.Name <> '.') and
>          (sr.Name <> '..') then
>       Begin
>          GetFileList(Sr);              { Error occurs here}
>       end
>       else
>       Begin
>          if FileExists(Path.Text + '\' + sr.Name) then
>             ListBox1.Items.Add(Path.Text+'\'+sr.Name);
>       end;
>       Found := FindNext(sr);
>       Application.ProcessMessages;
>    end;
>    FindClose(sr);
> end;

> The function is suppose to fill a ListBox with the entire contents of a
> specified drive/path.  What happens is this;  First time through, it
> retrieves a file called "LASTDISK", which doesn't exist on the floppy disk
> at all???

> Second time through, it retrieves a directory name called "CIVILWAR", which
> DOES exist, so, it tries to recurse so it can get the file names and add
> them to the list.  But, as soon as it hits the "GetFileList" line marked
> above, it blows up with a "Runtime error 202 at 001:01EA".  Any idea what
> this is?  Is Recursion supported in Delphi 1?  If not, is there an
> alternative to what I am trying to do?

         There's no problem with recursion in D1. You need to set
the stack size large enough. And with the function above you need
an _infinite_ stack size, to handle the infinite recursion that
results.

         Think about what hapens when the test

((sr.Attr and faDirectory) > 0) and
         (sr.Name <> '.') and
         (sr.Name <> '..')

returns True. You call GetFileList(Sr). You haven't modified Sr, so the
test is going to return True on the nested call. So that's going to
call GetFileList(Sr) again...

       Some people say you should avoid recursion here anyway,
lest you run out of stack space even when the recursion is set
up properly. They may well be right - it's certainly going to
be a bigger issue in D1 than D2 (because strings are larger and
stacks are smaller). If you want a recursive FindNext routine
you can find one in the _comments_ in the source, somewhere in
the neighborhood of FindFirst and FindNext. You could probably
modify that example to suit your purpose. (You should modify
it carefully, avoiding infinite loops.)

David C. Ullrich

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum

Re:Recursing in Delphi 1?


Quote
David A. Schweizer wrote:

> On Tue, 7 Jul 1998 18:31:07 -0400, "Jesse Castleberry"
> <D...@iThink.net> wrote:

> >I'm trying to run the following function in Delphi 1:

> >procedure TForm1.GetFileList(SR : TSearchRec);
> >Var
> >   Found : Integer;
> >begin
> >   Found := 0;
> >   while Found = 0 do
> >   Begin
> >      if ((sr.Attr and faDirectory) > 0) and
> >         (sr.Name <> '.') and
> >         (sr.Name <> '..') then
> >      Begin
> >         GetFileList(Sr);              { Error occurs here}
> >      end
> >      else
> >      Begin
> >         if FileExists(Path.Text + '\' + sr.Name) then
> >            ListBox1.Items.Add(Path.Text+'\'+sr.Name);
> >      end;
> >      Found := FindNext(sr);
> >      Application.ProcessMessages;
> >   end;
> >   FindClose(sr);
> >end;

> >The function is suppose to fill a ListBox with the entire contents of a
> >specified drive/path.  What happens is this;  First time through, it
> >retrieves a file called "LASTDISK", which doesn't

In addition to the ".." and "." directory paths, mentioned in a previous
reply to this posting, recursive directory-traversing algorithms can
also run into the problem of running out of search-records in DOS.  I'm
not exactly sure what the limit is, but if the directory tree is too
deep it stops working.

A non-recursive algorithm, however, works very reliably.  What you do is
to maintain an ordinary push-down stack.  When you encounter a directory
name you push the fully-qualified name of the directory onto that stack.
(A TStringList works nicely.)  Then, when you reach the end of the
current directory you pop a name and continue.

Basically:

        Push(initialDirectory);
        while NameStack.Count > 0 do begin
                PopName(currentDir);
                while Find ...
                        if name = '.' or name = '..' then continue;
                        if <directory entry>
                          then Push(<fully-qualified dirname>)
                          else <process file>
                end-while
                FindClose...
        end-while

Re:Recursing in Delphi 1?


In article <35A40C14.6...@primenet.com>,

Quote
  sund...@primenet.com wrote:
> David A. Schweizer wrote:

> > On Tue, 7 Jul 1998 18:31:07 -0400, "Jesse Castleberry"
> > <D...@iThink.net> wrote:

> > >I'm trying to run the following function in Delphi 1:

> > >procedure TForm1.GetFileList(SR : TSearchRec);
> > >Var
> > >   Found : Integer;
> > >begin
> > >   Found := 0;
> > >   while Found = 0 do
> > >   Begin
> > >      if ((sr.Attr and faDirectory) > 0) and
> > >         (sr.Name <> '.') and
> > >         (sr.Name <> '..') then
> > >      Begin
> > >         GetFileList(Sr);              { Error occurs here}
> > >      end
> > >      else
> > >      Begin
> > >         if FileExists(Path.Text + '\' + sr.Name) then
> > >            ListBox1.Items.Add(Path.Text+'\'+sr.Name);
> > >      end;
> > >      Found := FindNext(sr);
> > >      Application.ProcessMessages;
> > >   end;
> > >   FindClose(sr);
> > >end;

> > >The function is suppose to fill a ListBox with the entire contents of a
> > >specified drive/path.  What happens is this;  First time through, it
> > >retrieves a file called "LASTDISK", which doesn't

> In addition to the ".." and "." directory paths, mentioned in a previous
> reply to this posting, recursive directory-traversing algorithms can
> also run into the problem of running out of search-records in DOS.  I'm
> not exactly sure what the limit is, but if the directory tree is too
> deep it stops working.

        No doubt, not that I've ever had any problem with recursive
file searches. (The question of exactly what the limit is seems
sort of relevant here - if the limit is 2 then the example given in
the source code(!) is a very bad example, and needs to be fixed.
Otoh if the limit is 1000000 it's not likely to matter. I suspect
it's somewhere between the two. Just curious: _have_ you ever
actually had problems along these lines or is it just a theoretical
thing?)

      In any case that's not the problem _here_. Look at the code.
It requires an _infinite_ stack size. The original poster was
wondering whether maybe recursion doesn't work in D1 - given
that, seems like explaining that recursion works and explaining
why _this_ recursion won't work is a good idea; telling him to
do something else instead is not going to help the next time
he wants to write a recursive function.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum

Other Threads