home *** CD-ROM | disk | FTP | other *** search
- PROGRAM ByTypes;
- CONST
- HiValue = 127;
- NumAcross = 6;
-
- TYPE
- FieldType = (Names,Types);
- NameType = PACKED ARRAY[1..8] OF CHAR;
- TypeType = PACKED ARRAY[1..3] OF CHAR;
- EntryType = PACKED RECORD CASE BOOLEAN OF
- TRUE : (FName : NameType;
- FType : TypeType);
- FALSE : (FullEntry : PACKED ARRAY[1..11] OF CHAR);
- END;
- NodePtr = ^NodeType;
- NodeType = PACKED RECORD
- Info : EntryType;
- Junk : PACKED ARRAY[0..0] OF BYTE; { get a word boundary }
- Next : NodePtr;
- END;
- PTR = ^BYTE;
- STR16 = STRING[16];
-
- VAR
- Count : INTEGER;
- Drive : BYTE;
- FileSpec : STR16;
- ListHead : NodePtr;
- HiName : NameType;
- HiExt : TypeType;
- OutFile : TEXT;
- Result : INTEGER;
-
- EXTERNAL PROCEDURE CmdTail;
- EXTERNAL FUNCTION Argc : INTEGER;
- EXTERNAL PROCEDURE CmdTokn(Num : INTEGER; VAR S : STR16);
-
- EXTERNAL FUNCTION @BDOS86(Func : INTEGER; address : PTR) : INTEGER;
-
- PROCEDURE GetParms;
- VAR
- Temp : STR16;
-
- BEGIN { GetParms }
-
- CmdTail;
- Drive := 0;
- FileSpec := 'CON:';
- CmdTokn(1,Temp);
- CASE Argc OF
- 1 : BEGIN
- IF Temp[1] = '>' THEN FileSpec := COPY(Temp,2,LENGTH(Temp)-1)
- ELSE Drive := ORD(Temp[1]) - $40;
- END;
- 2 : BEGIN
- Drive := ORD(Temp[1]) - $40;
- CmdTokn(2,Temp);
- IF Temp[1] = '>' THEN DELETE(Temp,1,1);
- FileSpec := Temp;
- END;
- END; { Case }
-
- END; { GetParms }
-
- FUNCTION ReadDir : NodePtr;
- CONST
- FcbSize = 35;
- GetFirst = 17;
- GetNext = 18;
- SetDMA = 26;
-
- TYPE
- DirEntry = RECORD
- User : BYTE;
- Item : EntryType;
- Filler : PACKED ARRAY[1..20] OF BYTE;
- END;
- FcbType = PACKED ARRAY [0..FcbSize] OF BYTE;
-
- VAR
- Buffer : PACKED ARRAY[0..3] OF DirEntry;
- Fcb : FcbType;
- I,X : INTEGER;
- T : NodePtr;
-
- PROCEDURE InitFcb;
- BEGIN
-
- FILLCHAR(Fcb,SIZEOF(Fcb),CHR(0));
- FILLCHAR(Fcb[1],11,'?');
-
- END;
-
- BEGIN { ReadDir }
-
- InitFcb;
- Fcb[0] := Drive;
- T := ListHead;
- I := @BDOS86(SetDMA,ADDR(Buffer));
- I := @BDOS86(GetFirst,ADDR(Fcb));
- WHILE I <> 255 DO BEGIN
- Count := Count + 1;
- NEW(T^.Next);
- T := T^.Next;
- FOR X := 1 TO SIZEOF(EntryType) DO
- T^.Info.FullEntry[X] := CHR(ORD(Buffer[I].Item.FullEntry[X]) & $7F);
- I := @BDOS86(GetNext,ADDR(Fcb));
- END;
- T^.Next := ListHead;
- ReadDir := ListHead^.Next;
- ListHead^.Next := ListHead;
-
- END; { ReadDir }
-
- FUNCTION Merge(a,b : NodePtr; Field : FieldType) : NodePtr;
- VAR
- C : NodePtr;
-
- BEGIN { Merge }
-
- C := ListHead;
- IF Field = Names THEN
- REPEAT
- IF A^.Info.FName <= b^.Info.FName THEN BEGIN
- C^.Next := a;
- c := a;
- a := a^.Next;
- END
- ELSE BEGIN
- C^.Next := b;
- C := b;
- B := B^.Next;
- END;
- UNTIL C^.Info.FName = HiName
- ELSE
- REPEAT
- IF A^.Info.FType <= b^.Info.FType THEN BEGIN
- C^.Next := a;
- c := a;
- a := a^.Next;
- END
- ELSE BEGIN
- C^.Next := b;
- C := b;
- B := B^.Next;
- END;
- UNTIL C^.Info.FType = HiExt;
- Merge := ListHead^.Next;
- ListHead^.Next := ListHead;
-
- END; { Merge }
-
- FUNCTION MergeSort( C : NodePtr; Field : FieldType) : NodePtr;
- VAR
- A,B,Head,Todo,T : NodePtr;
- I,N : INTEGER;
-
- BEGIN { MergeSort }
-
- N := 1;
- NEW(Head);
- Head^.Next := C;
- REPEAT
- Todo := Head^.Next;
- C := Head;
- REPEAT
- T := Todo;
- A := T;
- FOR I := 1 TO N-1 DO T := T^.Next;
- B := T^.Next;
- T^.Next := ListHead;
- T := B;
- FOR I := 1 TO N-1 DO T := T^.Next;
- Todo := T^.Next;
- T^.Next := ListHead;
- C^.Next := Merge(a,b,Field);
- FOR I := 1 TO N+N DO C := C^.Next;
- UNTIL Todo = ListHead;
- N := N + N;
- UNTIL A = Head^.Next;
- MergeSort := Head^.Next;
- END; { MergeSort }
-
- PROCEDURE PrintEm(P : NodePtr);
- CONST
- Space = ' ';
-
- VAR
- Bord1 : PACKED ARRAY[1..39] OF CHAR;
- Bord2 : PACKED ARRAY[1..35] OF CHAR;
- Bottom : PACKED ARRAY[1..79] OF CHAR;
- LastOne : TypeType;
- NumPrinted : INTEGER;
-
- PROCEDURE DoBorder(VAR Exts : TypeType);
- BEGIN
-
- IF NumPrinted <> 0 THEN WRITELN(OutFile);
- WRITE(OutFile,Bord1);
- WRITE(OutFile,'[',Exts,']');
- WRITELN(OutFile,Bord2);
-
- END;
-
- BEGIN
-
- NumPrinted := 0;
- FILLCHAR(LastOne,SIZEOF(LastOne),CHR(HiValue));
- FILLCHAR(Bord1,SIZEOF(Bord1),'-');
- FILLCHAR(Bord2,SIZEOF(Bord2),'-');
- FILLCHAR(Bottom,SIZEOF(Bottom),'=');
- WHILE P <> ListHead DO BEGIN
- WITH P^.Info DO BEGIN
- IF FType <> LastOne THEN BEGIN
- DoBorder(FType);
- LastOne := FType;
- NumPrinted := 0;
- END;
- WRITE(OutFile,Space:5,FName);
- NumPrinted := NumPrinted + 1;
- IF NumPrinted = NumAcross THEN BEGIN
- WRITELN(OutFile);
- NumPrinted := 0;
- END;
- END;
- P := P^.Next;
- END;
- WRITELN(OutFile);
- WRITELN(OutFile,Bottom);
-
- END; { PrintEm }
-
- BEGIN { Main }
-
- GetParms;
- ASSIGN(OutFile,FileSpec);
- REWRITE(OutFile);
- IF IORESULT = 255 THEN BEGIN
- WRITELN('Can''t open ',FileSpec);
- EXIT;
- END;
- FILLCHAR(HiName,SIZEOF(NameType),CHR(HiValue));
- FILLCHAR(HiExt,SIZEOF(TypeType),CHR(HiValue));
- Count := 0;
- NEW(ListHead);
- WITH ListHead^.Info DO BEGIN
- FName := HiName;
- FType := HiExt;
- END;
- ListHead^.Next := NIL;
- PrintEm(MergeSort(MergeSort(ReadDir,Names),Types));
- WRITE(OutFile,Count:5,' File(s) listed');
- WRITELN(OutFile,' [by_Types v1.5]');
- CLOSE(OutFile,Result);
-
- END.