[Back to MISC SWAG index] [Back to Main SWAG index] [Original]

    {-------------------------------------------------------------}
    {                  Small SWAG LISTER                          }
    {            (c) 1996 by Valery Votintsev                     }
    {                         E-Mail: vot@infolink.tver.su        }
    {                         FIDO:   2:5021/2.30                 }
    {          modified slightly by Gayle Davis                   }
    {-------------------------------------------------------------}
    Program SWAGL;

    Uses DOS;

    TYPE
      SwagHeader =
        RECORD
          HeadSize : BYTE;                 {size of header}
          HeadChk  : BYTE;                 {checksum for header}
          HeadID   : ARRAY [1..5] OF CHAR; {compression type tag}
          NewSize  : LONGINT;              {compressed size}
          OrigSize : LONGINT;              {original size}
          Time     : WORD;                 {packed time}
          Date     : WORD;                 {packed date}
          Attr     : WORD;                 {file attributes and flags}
          BufCRC   : LONGINT;              {32-CRC of the Buffer }
          Swag     : STRING[12];           {stored SWAG filename}
          Subject  : STRING[40];           {snipet subject}
          Contrib  : STRING[35];           {contributor}
          Keys     : STRING[70];           {search keys, comma deliminated}
          FName    : PathStr;              {filename (variable length)}
          CRC      : WORD;                 {16-bit CRC (immediately follows FName)}
        END;

        SWAGFooter =
        RECORD
           CopyRight : String[60];         { GDSOFT copyright }
           Title     : String[65];         { SWG File Title   }
           Count     : INTEGER;
        END;

        ShortHeader =
        RECORD
          OrigSize : LONGINT;               {original size}
          Date     : WORD;                  {packed date}
          Subject  : STRING[40];            {snipet subject}
          Contrib  : STRING[35];            {contributor}
        END;

    Var
       PMask,
       FMask: String;                       { SWAG files mask      }
       Buf: SwagHeader;                     { Temporary buffer     }
       Footer:SWAGFooter;                   { SWAG file footer     }
       NextPos:LongInt;                     { Next snipet position }
       fSize:LongInt;                       { File size            }
       aList:Array[1..2000] of Pointer;     { Array of snipet info }
       pShortHeader: ^ShortHeader;          { snipet info pointer  }
       ListLen:Integer;                     { Snipet array length  }
       Snipets:Integer;                     { Number of snipets    }
       AllSize:LongInt;                     { All snipets size     }
       TotalSize:LongInt;                   { Total size           }
       F:File;
       DirInfo:SearchRec;
       i:integer;
       Dir: DirStr;
       Name: NameStr;
       Ext: ExtStr;

    {----------------------------------------------}
    { Convert the string to upper case             }
    {(Russian conversion is excluded for simlicity)}

    Function StUpcase(S:String):String;
    Var
       i:integer;
       l:byte absolute S;
    begin
       StUpcase[0]:=Chr(l);
       For i:=1 to l do
          StUpcase[i]:=UpCase(S[i]);
    end;

    {----------------------------------------------}
    { Repeat the char n times                      }
    Function Replicate(C:Char;n:byte):String;
    Var
       i:integer;
    begin
       Replicate[0]:=Chr(n);
       For i:=1 to n do
          Replicate[i]:=C;
    end;

    {----------------------------------------------}
    { String Pad Right                             }
    Function PadR(S:String;n:byte):String;
    Var
       i:integer;
       l:byte absolute S;
    begin
       PadR:=S;
       PadR[0]:=Chr(n);
       For i:=l+1 to n do
       begin
          PadR[i]:=' ';
       end;
    end;

    {----------------------------------------------}
    { Convert Integer to string & add leading zero }
    Function LeadZero(L:Longint;n:byte):String;
    Var
       i:integer;
       S:String;
    begin
       STR(L:n,S);
       For i:=1 to n do
          If S[i]=' ' then S[i]:='0';
       LeadZero:=S;
    end;
    {-------------------------------------------}
    { Convert packed date to string }
    Function Date2str(D:Word):String;
    Var
       Day  :Word;
       Month:Word;
       Year :Word;
    begin
       Day  := ( D and $1F);
       Month:= ( D and $1E0) shr 5;
       Year := ( D and $FE00) shr 9;
       Date2str:=LeadZero(Day,2)+'-'
                +LeadZero(Month,2)+'-'
                +LeadZero((Year+80),2);
    end;

    {--------- Main Routine ---------------------------------------}
    begin
       FMask := ParamStr(1); { Get the file mask from command line }
       If FMask <> '' then
       begin
          FSplit(FMask, PMask, Name, Ext);

          FindFirst(FMask,ARCHIVE,DirInfo); { Search first file }

          Writeln('');
          Writeln('================= SWAG Snipets List ==================');
          Writeln('   (c) 1996 by Valery Votintsev (vot@infolink.tver.su)');
          Writeln('');
          Writeln('From                 Size   Date   Subject');
          Writeln('------------------- ----- -------- ---------------');

          TotalSize:=0;
          Snipets  :=0;

          While DOSError = 0 do   { while files exists }
          begin
             FSplit(DirInfo.Name, Dir, Name, Ext);
             If StUpcase(Ext)='.SWG' then begin    { Skip not .SWG files }
                Assign(F,Pmask + DirInfo.Name);
                Reset(F,1);

                NextPos:=0;
                FSize:=FileSize(F);
                AllSize:=0;
                ListLen:=0;

                While (nextPos+SizeOf(Buf)) < FSize do
                begin
                   Seek(F,NextPos);
                   BlockRead(F,Buf,SizeOf(Buf));

                   New ( pShortHeader ); {Allocate memory}
                   Inc(ListLen);
                   aList[ListLen]:=pShortHeader;

                   With pShortHeader^ do
                   begin
                      OrigSize := Buf.OrigSize;
                      Date     := Buf.Date;
                      Subject  := Buf.Subject;
                      Contrib  := Buf.Contrib;

                      Inc(AllSize,OrigSize);
                   end;
                   NextPos:=NextPos+Buf.HeadSize+buf.NewSize+2;
                end;

                SEEK (F, FileSize(F) - SIZEOF(Footer));
                BlockRead(F,Footer,SizeOf(Footer));
                Close(F);

                { Say snipet header }
                Writeln('');
                Writeln(PadR(StUpcase(DirInfo.Name),12),' - ',Footer.Title);
                i:=Length(Footer.Title)+15;
                Writeln(Replicate('~',i));

                { List snipets in the file }
                For i:=1 to ListLen do
                begin
                   pShortHeader:=aList[i];

                   { Say the snipet info}
                   With pShortHeader^ do
                   begin
                      Write  (PadR(Contrib,19),' ');
                      Write  (OrigSize:5,' ');
                      Write  (Date2str(Date),' ');
                      Writeln(PadR(Subject,40));
                   end;
                   Dispose (pShortHeader); {Release memory}
                end;

                Inc(Snipets,ListLen);
                Inc(TotalSize,AllSize);

                { Say this file totals}
                Writeln('------------------- -----');
                Writeln(ListLen:13,AllSize:12);
             end; {If Ext = .SWG }
             FindNext(DirInfo);  { Search next file }
          end; {While DosError}

          { Say totals}
          Writeln('------------------- -----');
          Writeln('Total:',Snipets:7,TotalSize:12,' bytes');
          Writeln('');
       end; {If Mask <> ''}
    end.

[Back to MISC SWAG index] [Back to Main SWAG index] [Original]