MODULE FileInfo ;

FROM GlobalString IMPORT GetGlobalStringName , GetGlobalString ;

FROM Program IMPORT Verbosity , HelpRequired , IdentifyRequired ;

IMPORT Program ;

IMPORT Debug ;

FROM String IMPORT LengthC ;

FROM DecodeArg IMPORT DecodedInformation , DecodeInit , DecodeEnd ,
                      GetNumberOfValues , GetStringArg , GetStateArg ;


FROM IO IMPORT FindInput , SelectInput , FindOutput , SelectOutput ,
               CloseStream , ErrorStream , OutputStream ,
               WriteByte , SWriteByte , ReadByte ;

FROM File IMPORT Touch , GetDateStamp ;
FROM TimeAndDate IMPORT TimeStamp , TextualTimeOfBinaryTime ;



(* ------------------------------------------------------------------------- *)

PROCEDURE Check( This : INTEGER ) : BOOLEAN ;
BEGIN
   IF This < 0 THEN
      IF Result = 0 THEN
         Result := This ;
      END (* if *) ;
      RETURN FALSE ;
   ELSE
      RETURN TRUE ;
   END (* if *) ;
END Check ;

(* ------------------------------------------------------------------------- *)

PROCEDURE SWrch( Stream : CARDINAL ; Ch : CHAR ) ;
VAR
   Junk                    : INTEGER ;
BEGIN
   Junk := SWriteByte( Stream , INTEGER( Ch ) ) ;
   IF Junk < 0 THEN
      Debug.WriteS( "*NWriteByte failed : Result = " ) ;
      Debug.WriteH( Junk ) ;
      Debug.WriteS( "*N" ) ;
      IF Result = 0 THEN
         Result := Junk ;
      END (* if *) ;
   END (* if *) ;
END SWrch ;

(* ------------------------------------------------------------------------- *)

PROCEDURE SWriteS( Stream : CARDINAL ; Text : ARRAY OF CHAR ) ;
VAR
   Index                   : CARDINAL ;
   Ch                      : CHAR ;
BEGIN
   Index := 0 ;
   Length := LengthC( Text ) ;
   WHILE Index < Length DO
      Ch := Text[ Index ] ;
      IF Ch = '*' THEN
         INC( Index ) ;
         Ch := Text[ Index ] ;
         IF Ch = 'N' THEN
            Ch := 012C ;
         ELSE
            SWrch( Stream , '*' ) ;
         END (* if *) ;
      END (* if *) ;
      SWrch( Stream , Ch ) ;
      INC( Index ) ;
   END (* while *) ;
END SWriteS ;



(* ------------------------------------------------------------------------- *)

PROCEDURE Wrch( Ch : CHAR ) ;
VAR
   Junk                    : INTEGER ;
BEGIN
   Junk := WriteByte( INTEGER( Ch ) ) ;
   IF Junk < 0 THEN
      Debug.WriteS( "*NWriteByte failed : Result = " ) ;
      Debug.WriteH( Junk ) ;
      Debug.WriteS( "*N" ) ;
      IF Result = 0 THEN
         Result := Junk ;
      END (* if *) ;
   END (* if *) ;
END Wrch ;

(* ------------------------------------------------------------------------- *)

PROCEDURE WriteS( Text : ARRAY OF CHAR ) ;
VAR
   Index                   : CARDINAL ;
   Ch                      : CHAR ;
BEGIN
   Index := 0 ;
   Length := LengthC( Text ) ;
   WHILE Index < Length DO
      Ch := Text[ Index ] ;
      IF Ch = '*' THEN
         INC( Index ) ;
         Ch := Text[ Index ] ;
         IF Ch = 'N' THEN
            Ch := 012C ;
         ELSE
            Wrch( '*' ) ;
         END (* if *) ;
      END (* if *) ;
      Wrch( Ch ) ;
      INC( Index ) ;
   END (* while *) ;
END WriteS ;

(* ------------------------------------------------------------------------- *)

PROCEDURE GiveHelp() ;
VAR
   E                                    : INTEGER ;
BEGIN
   E := ErrorStream() ;
   SWriteS( E , Version ) ;
   SWriteS( E , "Give Information on one or more files*N" ) ;
   SWriteS( E , "Keywords :*N" ) ;
   SWriteS( E , "  Name     : List of ( wild card ) file names*N" ) ;
   SWriteS( E , "  To       : Where to print the output*N" ) ;
   SWriteS( E , "  Identify : Prints name and version number*N" ) ;
   SWriteS( E , "  Help     : Prints this information*N" ) ;
END GiveHelp ;

(* ------------------------------------------------------------------------- *)

PROCEDURE DescribeFile( VAR FileName : ARRAY OF CHAR ) ;
VAR
   E                             : INTEGER ;
   RealName                      : ARRAY [ 0..255 ] OF CHAR ;
   DateStamp                     : TimeStamp ;
   Time                          : ARRAY [ 0..40 ] OF CHAR ;
   Length                        : CARDINAL ;
BEGIN
   RealName := "????" ;
   WriteS( "File: " ) ;
   WriteS( FileName ) ;
(*
   WriteS( " [ " ) ;
   WriteS( RealName ) ;
   WriteS( " ]" ) ;
*)
   IF ( GetDateStamp( DateStamp , FileName ) >= 0 ) AND
      ( TextualTimeOfBinaryTime( Time , Length , DateStamp ) >= 0 ) THEN
      WriteS( " is datestamped " ) ;
      Time[ Length ] := 0C ;
      WriteS( Time ) ;
   ELSE
      WriteS( " is not datestamped") ;
   END (* if *) ;
   WriteS( "*N" ) ;
END DescribeFile ;

(* ------------------------------------------------------------------------- *)


VAR

Result                     : INTEGER ;
Index                      : CARDINAL ;
NumberOfFiles              : CARDINAL ;
Input                      : INTEGER ;
Output                     : INTEGER ;
Parameter                  : ARRAY [ 0..255 ] OF CHAR ;
Length                     : CARDINAL ;
Handle                     : DecodedInformation ;
Junk                       : BOOLEAN ;
KeyString                  : ARRAY [ 0..80 ] OF CHAR ;
Version                    : ARRAY [ 0..30 ] OF CHAR ;
ArgumentString             : ARRAY [ 0..255] OF CHAR ;
ArgumentLength             : CARDINAL ; 

BEGIN

Result := 0 ;

KeyString := "File/?/E/A To/K[ Output: ] Touch/S Identify/S Help/S" ;
Version := "Finfo Version 0.01/04*N" ;

ArgumentLength := Program.Arguments ( ArgumentString );
IF Check( DecodeInit( Handle , KeyString , ArgumentString ) ) THEN
END (* if *) ;   
IF HelpRequired( Handle , Result ) THEN
   GiveHelp() ;
   Program.Stop (0) ;
ELSE
   IF IdentifyRequired( Handle , Result ) THEN
      SWriteS( ErrorStream() , Version ) ;
      IF Result < 0 THEN
         Program.Stop (0) ;
      END (* if *) ;
   END (* if *) ;
END (* if *) ;
IF Result = 0 THEN
   Junk := Check( GetNumberOfValues( NumberOfFiles , "File" , Handle ) ) ;
   IF Check( GetStringArg( Parameter , Length , "To" , 1 , Handle ) ) THEN
      Parameter[ Length ] := 0C ;
      Output := FindOutput( Parameter ) ;
      Junk := Check( Output ) AND Check( SelectOutput( Output ) ) ;
   END (* if *) ;
   Index := 1 ;
   WHILE ( Result = 0 ) AND ( Index <= NumberOfFiles ) DO
      IF Check( GetStringArg( Parameter , Length ,
                              "File" , Index , Handle ) ) THEN
         Parameter[ Length ] := 0C ;
         DescribeFile( Parameter ) ;
      END (* if *) ;
      INC( Index ) ;
   END (* while *) ;
   IF Output >= 0 THEN
      Junk := Check( CloseStream( Output ) ) ;
   END (* if *) ;
   Junk := Check( DecodeEnd( Handle ) ) ;
END (* if *) ;
Program.Stop( Result ) ;

END FileInfo.
