TYPE
    WildExpandRegisters =
	RECORD
	CASE INTEGER OF
	 1: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : INTEGER);
	 2: (AL, AH, BL, BH, CL, CH, DL, DH	       : BYTE)
	END;

CONST
    WildExpandFlagCarry 	= $0001;

TYPE
    WildExpandMsDosBlock =
	RECORD
	Reserved01		: ARRAY [1..21] OF BYTE;
	FileAttributes		: BYTE;
	FileTime		: INTEGER;
	FileDate		: INTEGER;
	FileSizeLow		: INTEGER;
	FileSizeHigh		: INTEGER;
	FileName		: ARRAY [1..13] OF CHAR
	END;

CONST
    WildExpandPathLength	= 255;

TYPE
    WildExpandPathSpec		= STRING [WildExpandPathLength];

    WildExpandHistory =
	RECORD
	MSDosBlock		: WildExpandMsDosBlock;
	LeadingInformation	: WildExpandPathSpec;
	CurrentlyValid		: BOOLEAN;
	END;

VAR
    WildExpandHistoryBlock	: WildExpandHistory;


FUNCTION WildExpandInitialize
   (	PathName  : WildExpandPathSpec;
	MatchAttr : INTEGER) : BOOLEAN;

    VAR
	LastSlashIndex	: INTEGER;
	OldDTA		: ^ CHAR;
	Registers	: WildExpandRegisters;
	SearchIndex	: INTEGER;

    BEGIN

    {  Obtain leading path spec information.  }

    LastSlashIndex := 0;
    FOR SearchIndex := 1 TO Length (PathName)
    DO
	IF (PathName [SearchIndex] = '/') OR
	   (PathName [SearchIndex] = '\') OR
	   (PathName [SearchIndex] = ':')
	THEN
	    LastSlashIndex := SearchIndex
	ELSE
	    PathName [SearchIndex] := UpCase (PathName [SearchIndex]);
    WildExpandHistoryBlock.LeadingInformation :=
	Copy (PathName, 1, LastSlashIndex);

    {  If the pattern ends in a terminator, assume *.*	}

    IF LastSlashIndex = Length (PathName)
    THEN
	Insert ('*.*', PathName, Length (PathName) + 1);

    {  Save the current disk transfer address.	}

    Registers.AH := $2F;
    MsDos (Registers);
    OldDTA := Ptr (Registers.ES, Registers.BX);

    {  Have MS-DOS initialize the block.  }

    Registers.AH := $1A;
    Registers.DS := Seg (WildExpandHistoryBlock.MSDosBlock);
    Registers.DX := Ofs (WildExpandHistoryBlock.MSDosBlock);
    MsDos (Registers);

    PathName := PathName + #$00;
    Registers.AH := $4E;
    Registers.DS := Seg (PathName [1]);
    Registers.DX := Ofs (PathName [1]);
    Registers.CX := MatchAttr;
    MsDos (Registers);

    {  But '.' and '..' are not desired  }

    WHILE ((Registers.Flags AND WildExpandFlagCarry) = 0) AND
	  (WildExpandHistoryBlock.MSDosBlock.FileName [1] = '.')
    DO
	BEGIN

	Registers.AH := $4F;
	MsDos (Registers)

	END;

    WildExpandHistoryBlock.CurrentlyValid :=
	(Registers.Flags AND WildExpandFlagCarry) = 0;

    {  Reset the disk transfer address.  }

    Registers.AH := $1A;
    Registers.DS := Seg (OldDTA ^);
    Registers.DX := Ofs (OldDTA ^);
    MsDos (Registers);

    {  Return whether successful.  }

    WildExpandInitialize := WildExpandHistoryBlock.CurrentlyValid

    END;

PROCEDURE WildExpandContinue						{011}
   (VAR ResultName : WildExpandPathSpec;				{011}
    VAR ResultAttr : INTEGER);						{011}

    VAR
	Registers : WildExpandRegisters;
	ScanIndex : INTEGER;
	OldDTA	  : ^ CHAR;

    BEGIN

    IF NOT WildExpandHistoryBlock.CurrentlyValid
    THEN

	BEGIN

	{  Save the current disk transfer address.  }

	Registers.AH := $2F;
	MsDos (Registers);
	OldDTA := Ptr (Registers.ES, Registers.BX);

	{  Get the next path specification.  }

	Registers.AH := $1A;
	Registers.DS := Seg (WildExpandHistoryBlock.MSDosBlock);
	Registers.DX := Ofs (WildExpandHistoryBlock.MSDosBlock);
	MsDos (Registers);

	Registers.AH := $4F;
	MsDos (Registers);

	WildExpandHistoryBlock.CurrentlyValid :=
	    (Registers.Flags AND WildExpandFlagCarry) = 0;

	{  Reset the disk transfer address.  }

	Registers.AH := $1A;
	Registers.DS := Seg (OldDTA ^);
	Registers.DX := Ofs (OldDTA ^);
	MsDos (Registers)

	END;

    IF WildExpandHistoryBlock.CurrentlyValid
    THEN

	BEGIN
	ScanIndex := 1;
	WHILE WildExpandHistoryBlock.MsDosBlock.FileName [ScanIndex] <> #$00
	DO
	    ScanIndex := ScanIndex + 1;
	ResultName := WildExpandHistoryBlock.LeadingInformation +	{011}
	    Copy (WildExpandHistoryBlock.MsDosBlock.FileName, 1,
		ScanIndex - 1);
	ResultAttr := WildExpandHistoryBlock.MsDosBlock.FileAttributes; {011}
	WildExpandHistoryBlock.CurrentlyValid := FALSE
	END

    ELSE
	BEGIN								{011}

	ResultName := '';						{011}
	ResultAttr := 0 						{011}

	END								{011}
    END;
