[comp.lang.pascal] FindFirst

elric%FSU@pucc.princeton.edu (Commodore 128 User) (07/11/90)

In regards to the guy who was having the "no more files" error, maybe it is
obvious - maybe there are no more files.  Also, in the findfirst and findnext
commands did you search for 'anyfile'?  This could give you problems since it
also gives you subdirectory names as I discovered the hard way.  You need to
have it search for 'archive' type files.  Those are the actual files, not
the subdirectory names.  Hope that helps.

chad@csd4.csd.uwm.edu (D. Chadwick Gibbons) (07/11/90)

In article <23854@adm.BRL.MIL> elric%FSU@pucc.princeton.edu  writes:
|In regards to the guy who was having the "no more files" error, maybe it is
|obvious - maybe there are no more files.  Also, in the findfirst and findnext
|commands did you search for 'anyfile'?  This could give you problems since it
|also gives you subdirectory names as I discovered the hard way.  You need to
|have it search for 'archive' type files.  Those are the actual files, not
|the subdirectory names.  Hope that helps.

unfortunately, you don't want to do that.  specifing archive files may
seem the right thing to do, but thing of when you backup using any decent
backup system: the archive bits are unset until that file is modified
again.  thus, you can be searching for an file that _is_ there but isn't
archived.

in reference to the other individual: check that you are not corrupting
your search record.  that's a common problem and sounds like the problem
in your case.  be sure your recursive routines allow modification of the
search record or that the search record is a global variable.
--
D. Chadwick Gibbons, chad@csd4.csd.uwm.edu, ...!{rutgers,uunet}!uwm!uwmcsd4!chad

bg11+@andrew.cmu.edu (Brian E. Gallew) (07/11/90)

I have declared my search record as a global _const_.  Perhaps that is
my problem.  

Source code to follow soon.

bg11+@andrew.cmu.edu (Brian E. Gallew) (07/13/90)

I managed to fix the problem using some code someone sent me, but here
is the buggy stuff:
uses Crt,DOS;
const
  DungeonPath = 'd:\tp\d&d\dmaze.???';

type
  FileNameListTypePtr = ^FileNameListType;
  FileNameListType = record
    Filerecord:SearchRec;
    Next:FileNameListTypePtr;
    end;

var
  Head:FileNameListTypePtr;

Function GetFileNameList(Firstlook:Boolean):FilenameListTypePtr;
var
Head:FileNameListTypePtr;

begin
New(Head);
  If Firstlook then
    FindFirst(DungeonPath,AnyFile,Head^.FileRecord)
  else
    FindNext(Head^.FileREcord);

if DosError=0 then
  begin
  Head^.Next:=GetFileNameList(False);
  GetFileNameList:=Head;
  end
else
  begin
  Dispose(Head);
  GetFileNameList:=Nil;
  end;
end;

Procedure LoseFileNameList(var Head:FileNameListTypePtr);
begin
if Head^.Next=Nil then Dispose(Head) else LoseFileNameList(Head^.Next);
end;

Procedure DrawList(Head:FileNameListTypePtr);
var
  x:Integer;
begin
x:=0;
clrscr;
gotoxy(1,1);
While Head<>Nil do
  begin
  Write(Head^.Filerecord.Name);
  x:=succ(x);
  Head:=Head^.Next;
  if x>4 then begin writeln; x:=0; end else gotoxy(x*16+1,WhereY);
  end;
end;

Function GetItem(head:FileNameListTypePtr; Which:Integer):FileNameListTypePtr;
begin
If (not (Head=Nil) and (Which<1)) then GetItem:=GetItem(Head^.Next,Which-1)
  else GetItem:=Nil;
end;

Function CountList(Head:FileNameListTypePtr):Integer;
begin
If Head=Nil then
  Countlist:=0
else
  Countlist:=1+CountList(Head^.Next);
end;

Function ShowFileNameList(var Head:FileNameListTypePtr):FileNameListTypePtr;
var
  x,y,NewX,NewY,Count:integer;
  REady:Boolean;
  ch:Char;

begin
if Head<>Nil then
  begin
  Count:=CountList(Head);
  DrawList(Head);
  REady:=False;
  x:=0; y:=0; NewX:=0; NewY:=0;
    Repeat
    write(GetItem(Head,y*5+x)^.FileRecord.Name);
    ch:=Readkey;
    case ord(ch) of
      0:begin
        ch:=ReadKey;
        case ord(ch) of
          75:{cursor up};
          76:{cursor down};
          77:{cursor left};
          78:{cursor right};
          79:{home};
          80:{end};
          end;
        end;
      50:{cursor down};
      56:{cursor up};
      54:{cursor right};
      56:{cursor left};
      55:{home};
      49:{end};
      13:REady:=True;
    end;
    write(GetItem(Head,y*5+x)^.FileRecord.Name);
    x:=NewX; y:=NewY;
    until Ready;
  ShowFileNameList:=GetItem(Head,y*5+x);
  end
else
  ShowFileNameList:=Nil
end;

begin
Head:=GetFileNameList(True);
Head:=ShowFileNameList(Head);
Gotoxy(1,24);Write(Head^.FileRecord.Name);
end.

silk@dhw68k.cts.com (Mitch Gorman) (07/14/90)

In article <23854@adm.BRL.MIL> elric%FSU@pucc.princeton.edu (Commodore 128 User) writes:
> You need to have it search for 'archive' type files.  [...]

	NO, I SAY.  Now, I say 'nay'!!

	What if you've just used [fill in your favorite disk backup program
here] to back up your disk.  If you tell/allow it, that program will usually
go back and changed all those files' attributes to _TURN_OFF_ the archive flag.

	The smart way to do this, guaranteed to find any and all honest-to-god
files, is "findfirst(..., anyfile - directory - volumeid, ...);".  

	And dat's da twooth.


_______________________________________________________________________________
	Mitch Gorman		Internet:  silk@dhw68k.cts.com
				uucp:  ...{spsd,zardoz,felix}!dhw68k!silk
-------------------------------------------------------------------------------
"Never seen the same face twice, never walked the same way;
 	And the little love that I have known I keep to myself."
		- Genesis, "Say It's Alright, Joe", _And Then There Were Three_
_______________________________________________________________________________

bgeer@esunix.UUCP (Bob Geer) (07/20/90)

From article <1990Jul13.232754.29083@dhw68k.cts.com>, by silk@dhw68k.cts.com (Mitch Gorman):
> In article <23854@adm.BRL.MIL> elric%FSU@pucc.princeton.edu (Commodore 128 User) writes:
>> You need to have it search for 'archive' type files.  [...]
>... 
> 	The smart way to do this, guaranteed to find any and all honest-to-god
> files, is "findfirst(..., anyfile - directory - volumeid, ...);".  
> 

Back in the Turbo Pascal 1 & DOS 2 days I wrote a directory browser
using DOS software interrupt calls since there was no "findfirst()"
library procedure.  I have listed below the file attribute byte
breakdown, a code fragment that searches for either all files or
non-hidden, non-system files (volume label & sub-dirs were handled
specially), and the breakdown of the FCB & DTA records, that resulted
from that experience.  Hopefully seeing this stuff will shed some
light on directory searches from within a program.

BG -- Bear-person

_______________________________________________________________________________
CONST
  READ_ONLY       = $01   ; { file attribute byte map }
  HIDDEN          = $02   ; { " }
  SYSTEM          = $04   ; { " }
  VOLUME_LABEL    = $08   ; { " }
  SUB_DIRECTORY   = $10   ; { " }
  ARCHIVE         = $20   ; { " }

  VAR { local }
     attributes : BYTE ;

  IF write_all_files THEN
     attributes := $FF - VOLUME_LABEL - SUB_DIRECTORY { everything! }
     {attributes := ARCHIVE + READ_ONLY + SYSTEM + HIDDEN}
     ELSE
     attributes := ARCHIVE + READ_ONLY ;

TYPE
  FCB_RECORD       = RECORD { used by DOS 1.x filing calls }
                     extended_fcb_flag  : BYTE ;
                     unused1            : ARRAY [2..6] OF BYTE ;
                     attribute          : BYTE ;
                     fcb_drive_number   : BYTE ;
                     file_name          : ARRAY [1..8]  OF BYTE ;
                     extension          : ARRAY [9..11] OF BYTE ;
                     block_number       : INTEGER ;
                     record_size        : INTEGER ;
                     low_size           : INTEGER ;
                     high_size          : INTEGER ;
                     created_date       : INTEGER ;
                     reserved1          : ARRAY [22..31] OF BYTE ;
                     seq_record_no      : BYTE ;
                     low_ran_record_no  : INTEGER ;
                     high_ran_record_no : INTEGER ;
                     END ;

  DTA_RECORD       = RECORD { used by DOS 2.x filing calls }
                     used_by_dos   : ARRAY[1..21] OF BYTE ;
                     attribute     : BYTE ;
                     time          : INTEGER ;
                     date          : INTEGER ;
                     low_size      : INTEGER ;
                     high_size     : INTEGER ;
                     file_name     : FILE_NAME ;
                     END ;


-- 
<> Bob Geer        <> at decwrl!esunix!bgeer or utah-cs!esunix!bgeer  <>
<>    Bear-person  <> speaking only for myself, one of my many tricks <>
<> Salt Lake City, <> "We must strive to be more than we are, Lal."   <>
<>          Ootah  <>           -- Cmdr. Data, learning schmaltz      <>

Robert_Salesas@mindlink.UUCP (Robert Salesas) (04/08/91)

I'm having a problem with FindFirst in Turbo Pascal 6.  I modified the List
demo by exluding the ReadOnly flag in the attributes.  This should not include
readonly files, yet it does.  Anyone have an idea why?

Rob
--
\--------------------------------------------------------------------/
\ Robert Salesas             + Usenet:  Robert_Salesas@MINDLINK.UUCP /
\ Eschalon Development Inc.  + CIS:     76625,1320    BYTE:  newdawn /
\--------------------------------------------------------------------/

fehr@ms.uky.edu (Jeff Davis) (04/10/91)

In article <5419@mindlink.UUCP> Robert_Salesas@mindlink.UUCP (Robert Salesas) writes:
>I'm having a problem with FindFirst in Turbo Pascal 6.  I modified the List
>demo by exluding the ReadOnly flag in the attributes.  This should not include
>readonly files, yet it does.  Anyone have an idea why?
>
It is my impression that the attribute parameter is used only to return a
value and is not checked by the routine.

-- 
davis@keats.ca.uky.edu
Is this a long trip or a short trip?

ballerup@diku.dk (Per Goetterup) (04/10/91)

Robert_Salesas@mindlink.UUCP (Robert Salesas) writes:

=>I'm having a problem with FindFirst in Turbo Pascal 6.  I modified the List
=>demo by exluding the ReadOnly flag in the attributes.  This should not include
=>readonly files, yet it does.  Anyone have an idea why?

Another related problem, maybe with the same cause:

Try simply to search for directories using the 'Directory' attribute mask
and you'll not only find directories but also close to everything else (I
think, perhaps VolumeID's excluded).

This is NOT directly a bug in TP because it also happens if you try the same
in assembler! - A bug in DOS it seems!

Perhaps Borland COULD have included a work-around in their code by simply
checking the found file's attributes and search again if it didn't match...

I do just that myself and it's not really a big bother, but still - it is
SUPPOSED to work...!

	Hack on...

		Per.

-- 
| Per Gotterup                        | "The most merciful thing in the    |
| Student, DIKU (Dept. of Comp. Sci.) | world, I think, is the inability   |
| University of Copenhagen, Denmark   | of the human mind to correlate all |
| Internet: ballerup@freja.diku.dk    | its contents."  - H.P. Lovecraft - |

Robert_Salesas@mindlink.UUCP (Robert Salesas) (04/11/91)

Yup, I actually understood a few days ago!  I was already checking the ATTRIB
for archive purposes, I just wanted to ignore READONLY files.
The docs really don't explain this at all, the msdos references do though.

Rob
--
\--------------------------------------------------------------------/
\ Robert Salesas             + Usenet:  Robert_Salesas@MINDLINK.UUCP /
\ Eschalon Development Inc.  + CIS:     76625,1320    BYTE:  newdawn /
\--------------------------------------------------------------------/

CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu ( Karl Brendel) (04/11/91)

In article <1991Apr10.134936.13981@odin.diku.dk>, ballerup@diku.dk
  (Per Goetterup) wrote:

>Try simply to search for directories using the 'Directory' attribute mask
>and you'll not only find directories but also close to everything else (I
>think, perhaps VolumeID's excluded).
>
>This is NOT directly a bug in TP because it also happens if you try the same
>in assembler! - A bug in DOS it seems!
>
>Perhaps Borland COULD have included a work-around in their code by simply
>checking the found file's attributes and search again if it didn't match...
>
>I do just that myself and it's not really a big bother, but still - it is
>SUPPOSED to work...!

I don't think this can be properly described as a "bug" in either
TPas or DOS, since it is documented in each case. Whether Borland's
FindFirst _should_ work so much like the equivalent DOS call is a
different question, but at least it works the way the manual _says_
it does.

Cheers--                        --Karl

+--------------------------------------------------------------------+
| Karl Brendel                           Centers for Disease Control |
| Internet: CDCKAB@EMUVM1.BITNET         Epidemiology Program Office |
| Bitnet: CDCKAB@EMUVM1                  Atlanta GA  30093       USA |
|                        Home of Epi Info 5.0                        |
+--------------------------------------------------------------------+

derek@sun4dts.dts.ine.philips.nl (derek) (04/11/91)

Findfirst/Findnext returns ALL ordinary files PLUS those files whose
attribute you specify. Once you have the file(s) you then have to check
the attribute yourself to eliminate those files you don't want. This is
not terribly well documented in the TP manuals. 

If you need more help, ask, but the above should be enough to clarify the
problem. (Hint, you have to look at the file record returned.)

Best Regards, Derek Carr
DEREK@DTS.INE.PHILIPS.NL           Philips I&E TQV-5 Eindhoven, The Netherlands 
Standard Disclaimers apply.

Robert_Salesas@mindlink.UUCP (Robert Salesas) (04/12/91)

Actual Karl, the TP manual implies it works differently than it does.  Their
examples even show the use of ARCHIVE when in fact you'll get the same files
whether you use the ARCHIVE bit or not.  Although there is nothing technically
wrong with this, it does confuse the matter by the implication that not
including ARCHIVE will exclude those files from the search.

Rob
--
\--------------------------------------------------------------------/
\ Robert Salesas             + Usenet:  Robert_Salesas@MINDLINK.UUCP /
\ Eschalon Development Inc.  + CIS:     76625,1320    BYTE:  newdawn /
\--------------------------------------------------------------------/

hoffmann@infopls.chi.il.us (Robert Hoffmann) (04/15/91)

ballerup@diku.dk (Per Goetterup) writes:

> Robert_Salesas@mindlink.UUCP (Robert Salesas) writes:
> 
> =>I'm having a problem with FindFirst in Turbo Pascal 6.  I modified the List
> =>demo by exluding the ReadOnly flag in the attributes.  This should not incl
> =>readonly files, yet it does.  Anyone have an idea why?
> 
> Another related problem, maybe with the same cause:
> 
> Try simply to search for directories using the 'Directory' attribute mask
> and you'll not only find directories but also close to everything else (I
> think, perhaps VolumeID's excluded).
 
From the manual (what, you don't have the manual? <GRIN>):
 
"The ATTR parameter specifies the special files to include (in addition 
to all normal files)."
 
You use FindFirst/FindNext to get the file, *then* compare 
(SearchRec).Attr to one of the predefined constants to see if the 
returned filespec matches what you want.
 
Rob
---------------------------------
hoffmann@infopls.chi.il.us

Robert_Salesas@mindlink.bc.ca (Robert Salesas) (04/15/91)

I fully understand that the files optained are in addition to "normal" files.
However, the manual does not say what normal files are, yet it does provide the
Archive and ReadOnly files in the ANYFILE constant AND
it provides an example with the ARCHIVE constant.  This implies that
Archive and Readonly return differet selections than if they are not used.
When I checked the norton guide, it said (_SPECIFICALLY_) that archive and
readonly files are returned regardless of the flags.  I
like Borland products VERY much, I own 4 of them, and I enjoy using htem.
However, the documentation is sparse and sometimes even misleading _in some
areas_.  Maybe if you're an old hand at TP and MSDOS you can read between the
lines, but a lot of newer people can't.
I'm not condemning them, I'm just saying that it could, and should, be
improved.
Rob
--
\--------------------------------------------------------------------/
\ Robert Salesas             + Usenet:  Robert_Salesas@MINDLINK.UUCP /
\ Eschalon Development Inc.  + CIS:     76625,1320    BYTE:  newdawn /
\--------------------------------------------------------------------/

CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu ( Karl Brendel) (04/16/91)

=========================================================================
Received: from CUNYVM.BITNET by EMUVM1.CC.EMORY.EDU (Mailer R2.03B) with BSMTP
 id 0966; Mon, 15 Apr 91 07:33:47 EDT
Received: from CUNYVM by CUNYVM.BITNET (Mailer R2.07) with BSMTP id 8142; Mon,
 15 Apr 91 07:36:11 EDT
Received: from VIM.BRL.MIL by CUNYVM.CUNY.EDU (IBM VM SMTP R1.2.2MX) with TCP;
 Mon, 15 Apr 91 07:36:11 EDT
Received: from VIM.BRL.MIL by VIM.BRL.MIL id aa27304; 15 Apr 91 7:26 EDT
Received: from adm.brl.mil by VIM.BRL.MIL id aa27053; 15 Apr 91 7:15 EDT
Received: from USENET by ADM.BRL.MIL id aa20675; 15 Apr 91 7:04 EDT
From: Robert Salesas <Robert_Salesas@mindlink.uucp>
Newsgroups: comp.lang.pascal
Subject: Re: FindFirst
Message-ID: <5461@mindlink.UUCP>
Date: 11 Apr 91 02:43:58 GMT
To:       info-pascal@BRL.MIL

Yup, I actually understood a few days ago!  I was already checking the ATTRIB
for archive purposes, I just wanted to ignore READONLY files.
The docs really don't explain this at all, the msdos references do though.

Rob
--
\--------------------------------------------------------------------/
\ Robert Salesas             + Usenet:  Robert_Salesas@MINDLINK.UUCP /
\ Eschalon Development Inc.  + CIS:     76625,1320    BYTE:  newdawn /
\--------------------------------------------------------------------/
    Re: FindFirst
=========================================================================
Received: from CUNYVM.BITNET by EMUVM1.CC.EMORY.EDU (Mailer R2.03B) with BSMTP
 id 0968; Mon, 15 Apr 91 07:34:05 EDT
Received: from CUNYVM by CUNYVM.BITNET (Mailer R2.07) with BSMTP id 8193; Mon,
 15 Apr 91 07:36:29 EDT
Received: from VIM.BRL.MIL by CUNYVM.CUNY.EDU (IBM VM SMTP R1.2.2MX) with TCP;
 Mon, 15 Apr 91 07:36:28 EDT
Received: from VIM.BRL.MIL by VIM.BRL.MIL id ab27304; 15 Apr 91 7:26 EDT
Received: from adm.brl.mil by VIM.BRL.MIL id aa27060; 15 Apr 91 7:16 EDT
Received: from USENET by ADM.BRL.MIL id aa20923; 15 Apr 91 7:11 EDT
From: Robert Salesas <Robert_Salesas@mindlink.uucp>
Newsgroups: comp.lang.pascal
Subject: Re: FindFirst
Message-ID: <5467@mindlink.UUCP>
Date: 11 Apr 91 18:11:28 GMT
To:       info-pascal@BRL.MIL

Actual Karl, the TP manual implies it works differently than it does.  Their
examples even show the use of ARCHIVE when in fact you'll get the same files
whether you use the ARCHIVE bit or not.  Although there is nothing technically
wrong with this, it does confuse the matter by the implication that not
including ARCHIVE will exclude those files from the search.

Rob
--
\--------------------------------------------------------------------/
\ Robert Salesas             + Usenet:  Robert_Salesas@MINDLINK.UUCP /
\ Eschalon Development Inc.  + CIS:     76625,1320    BYTE:  newdawn /
\--------------------------------------------------------------------/
    Re: FindFirst
=========================================================================

CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu ( Karl Brendel) (04/16/91)

In article <5467@mindlink.UUCP> Robert_Salesas@mindlink.uucp (Robert
  Salesas) wrote:

>Actual Karl, the TP manual implies it works differently than it
>does.  Their examples even show the use of ARCHIVE when in fact
>you'll get the same files whether you use the ARCHIVE bit or not.
>Although there is nothing technically wrong with this, it does
>confuse the matter by the implication that not including ARCHIVE
>will exclude those files from the search.

(First let me digress with an apology for having reposted two of
Robert's articles in the guise of a reply. I apparently quit my
reply rather than saving it, and uploaded the resulting file,
comprising his two articles. Oh, how I hate it when others do that.
<grin>)

Robert:

The Turbo Pascal 5.X manual says about FindFirst:

        The _Attr_ parameter specifies the special files to include
        (in addition to all normal files).

The FindFirst documentation has said essentially that same thing
ever since the routine was introduced. The example was poorly
chosen, and should have used Hidden, (SysFile?,) VolumeID or
Directory to illustrate FindFirst's behavior re _Attr_. However,
I've always found the statement quoted above to clearly describe the
behavior, and I don't see that it "implies" anything other than what
is stated. (A file is a "normal" file regardless of whether it has
the Archive bit set.)

Let's agree that you did not find the Turbo Pascal documentation
clear, but that you understood the "msdos references" (mentioned in
another article) and let it go at that. OK?

Cheers--                        --Karl

+--------------------------------------------------------------------+
| Karl Brendel                           Centers for Disease Control |
| Internet: CDCKAB@EMUVM1.BITNET         Epidemiology Program Office |
| Bitnet: CDCKAB@EMUVM1                  Atlanta GA  30093       USA |
|                        Home of Epi Info 5.0                        |
+--------------------------------------------------------------------+

reino@cs.eur.nl (Reino de Boer) (04/17/91)

Before this gets any more confusing....

In <5511@mindlink.bc.ca> Robert_Salesas@mindlink.bc.ca (Robert Salesas) writes:

>I fully understand that the files optained are in addition to "normal" files.
>However, the manual does not say what normal files are, yet it does provide the
>Archive and ReadOnly files in the ANYFILE constant AND
>it provides an example with the ARCHIVE constant.  This implies that
>Archive and Readonly return differet selections than if they are not used.
>When I checked the norton guide, it said (_SPECIFICALLY_) that archive and
>readonly files are returned regardless of the flags.
			     ^^^^^^^^^^NOT TRUE (see item 3 below)

The attribute controls the search as follows (freely translated from the
MS-DOS encyclopedia):
1.  If the attribute is $00, only normal files are included in the search.
2.  If the attribute has any combination of bits 1, 2, and 4 (Hidden,
    System, and Directory bits) set, the search includes normal files
    as well as files with any of the attributes specified.
3.  If the attribute has bit 3 set (VolumeID bit), only a matching
    volume label is returned.
4.  Bits 0 and 5 (ReadOnly and Archive bits) are ignored.
From which we can conclude that only Hidden, System, Directory, and
VolumeID bits indicate non-normal files.

Hope this helps -- Reino
-- 
Reino R. A. de Boer     "We want to build the right product right, right?"
Erasmus University Rotterdam ( Informatica )
e-mail: reino@cs.eur.nl