[comp.lang.pascal] Exists

NORM%IONAACAD.BITNET@tecmtyvm.mty.itesm.mx ( Norman Walsh) (02/15/91)

>2.  the file is not found if it's a read-only file on a network
>    drive. This is because untyped files (and any other non-text files)
>    are opened in update mode by reset( .. ).
>
First, I agree wholeheartedly with Reino's assertion that trying to
open the file is not the best solution to the problem.  However, the
fact that Turbo Reset()s untyped files in r/w mode can be overridden
by setting the FileMode variable to 0.

   SaveMode := FileMode; {which is usually 3, by the way}
   FileMode := 0;
   Reset(F);
   FileMode := SaveMode;

The above code will open any file "F" in r/o mode.

                                                  ndw

pp@wsinti01.info.win.tue.nl (Peter Peters) (02/18/91)

To add my 0.02$ about the questions about finding files, testing if
files exist and command line parameter processing the next unit and
program seem to fit nicely :-).
Use it as you like. Give credit where it's due....


-------------------------------------------------------------------
Unix like getopt
-------------------------------------------------------------------

Unit TPOpt;

Interface

Uses
  Dos;

Const
  EofChar  : Char = ^Z;                        (* End of file character *)
  MaxArg   = 15;

Type
  ArgRange = 0..MaxArg;

Var
  SwitChar : Char;                              (* Dos switch character *)
  OptErr   : Word;           (* Enable/Disable invalid switch detection *)
  OptInd   : Word;                                (* Current Argv index *)
  OptArg   : String;                             (* Argument for switch *)
  Argv     : Array[ArgRange] Of String;          (* Array of parameters *)
  Argc     : ArgRange;                      (* Number of parameters + 1 *)

Procedure ResetOptions;             (* (Re)Initialise option processing *)

Procedure SetEnvOpt ( EnvirOpt : String );    (* Set environment string *)

Function  GetOpt( Parm : String ) : Char;   (* Get a command line switch *)

Implementation

Var
  EnvOpt  : String;  (* Environment variable used as options/parameters *)
  Init    : Boolean;                     (* Initialisation done/needeed *)

Function GetSwitChar : Char;      (* Uses undocumented DOS function 37h *)
Var
  Regs : Registers;
Begin {getswitchar}
  Regs.ax := $3700;
  MsDos (Regs);
  GetSwitChar := Char(Regs.dl);
End {getswitchar};

Procedure SetEnvOpt{( EnvirOpt : String )};
Begin {setenvopt}
   EnvOpt := EnvirOpt;
End {setenvopt};

Function GetWord( Var Options : String ) : String;
Var
  OptS : String;
  Mn   : Byte;
Begin {getword}
  Repeat
    While (Length(Options) > 0) And (Options[1] = ' ') Do
      Delete(Options,1,1);
    Mn := Pos( ' ',Options+' ' );
    OptS := Copy( Options, 1, Mn-1 );
    Options := Copy( Options, Mn+1, 255 );
  Until (Options = '') Or (OptS <> '');
  GetWord := OptS;
End {getword};

Procedure ResetOptions;
Var
  i       : Byte;
  Options : String;
Begin {resetoptions}
  Argc := 0;
  Options := GetEnv( EnvOpt );
  Repeat
    OptArg := GetWord( Options );
    If OptArg[0] > #0 Then
      If OptArg[1] = SwitChar Then
        Begin
          Argv[Argc] := OptArg;
          If OptArg <> '' Then Inc( Argc );
        End {if};
  Until OptArg = '';
  For i := 1 To ParamCount Do
    Begin
      OptArg := ParamStr(i);
      If OptArg[0] > #0 Then
        If OptArg[1] = SwitChar Then
          Begin
            Argv[Argc] := OptArg;
            If OptArg <> '' Then Inc( Argc );
          End {if};
    End {for};
  Options := GetEnv( EnvOpt );
  Repeat
    OptArg := GetWord( Options );
    If OptArg[0] > #0 Then
      If OptArg[1] <> SwitChar Then
        Begin
          Argv[Argc] := OptArg;
          If OptArg <> '' Then Inc( Argc );
        End {if};
  Until OptArg = '';
  For i := 1 To ParamCount Do
    Begin
      OptArg := ParamStr(i);
      If OptArg[0] > #0 Then
        If OptArg[1] <> SwitChar Then
          Begin
            Argv[Argc] := OptArg;
            If OptArg <> '' Then Inc( Argc );
          End {if};
    End {for};
  For i := Argc To MaxArg Do
    Argv[i] := '';
  Init   := False;
  OptInd := 0;
  OptArg := '';
End {resetoptions};

Function GetOpt{( Parm : String ) : Char};
Var
  OptPos : Byte;
Begin {getopt}
  If Init Then ResetOptions;
  If (Optind < Argc) And (Argv[Optind,1] = SwitChar) Then
    Begin
      OptPos := Pos( Argv[Optind,2], Parm );
      If OptPos = 0 Then
        Begin
          If OptErr > 0 Then
            Writeln( ^M^J'Invalid switch : ', Copy( Argv[OptInd], 1, 2 ) );
          GetOpt := '?';
        End {if}
      Else
        Begin
          GetOpt := Argv[Optind,2];
          If (OptPos < Length( Parm )) And (Parm[OptPos+1] = ':') Then
            Begin
              OptArg := Copy( Argv[OptInd], 3, Length( Argv[OptInd] ) );
              If OptArg[1] = '=' Then
                Delete( OptArg, 1, 1 );
            End {if};
        End {else};
      Inc( OptInd );
    End {if}
  Else
    GetOpt := EofChar;
End {getopt};

Begin {main}
 SwitChar := GetSwitChar;
 OptErr   := 1;
 Init     := True;
 EnvOpt   := '';
End {main}.

----------------------------------------------------------------------
And here's a program that uses it, testing the attributes of a file.
----------------------------------------------------------------------

Program FaTest;
(* check if file attribute of the parameter is set,
   return doserror 0 to indicate check is ok, doserror 1 if not ok *)

Uses
  Dos, TpOpt;

Var
  S        : SearchRec;
  FileAttr : Byte;
  FileName : String;

Procedure ProcessParameters;
Var
  Par : Char;
Begin
  Repeat
    Par := Getopt( 'rRhHsSvVdDaAfF' );
    Case UpCase(Par) Of
      'R' : FileAttr := FileAttr Or ReadOnly;
      'H' : FileAttr := FileAttr Or Hidden;
      'S' : FileAttr := FileAttr Or SysFile;
      'V' : FileAttr := FileAttr Or VolumeId;
      'D' : FileAttr := FileAttr Or Directory;
      'A' : FileAttr := FileAttr Or Archive;
      'F' : FileAttr := FileAttr Or (AnyFile And (Not Directory));
      '?'     : Halt(1);
    End;
  Until Par = EofChar;
  FileName := Argv[Optind];
End;

Begin
  FileAttr := 0;
  ProcessParameters;
  FindFirst (FileName,AnyFile,S);
  If (S.Attr And FileAttr) = 0 Then
    Halt(1);
End.

--------------------------------------------------------------------

I'll try to answer questions.
Positive criticism I will accept.
Flames will be neglected.


-- 
| Peter Peters                              | UUCP  : pp@win.tue.nl     |
| Eindhoven University of Technology (TUE)  | PHONE : +31-(0)40-474120  |
| Dept. of Mathematics and Computer Science | TUE   : HG 8.82 / 4120    |
| Disclaimer : I said WHAT ???              | VHF   : pa0ppe            |