{***************************************************************************}
{                                                                           }
{                           File: PAS:OBJINTER.TEXT                         }
{                                                                           }
{              (C) Copyright 1981, 1982 Apple Computer, Inc.                }
{                                                                           }
{                            All rights reserved.                           }
{                                                                 11-Nov-82 }
{ 11-Nov-82 Fixed size bug, IULoc indexed by Unit#, not Seg#                }
{ 12-Oct-82 Added file format checking to Intrin                            }
{***************************************************************************}

{$I flags.text}

UNIT ObjInter;

  INTERFACE

    USES {$u n/ObjIOLib} PasDefs, MemMan, Trees, Utility, FileIO, ObjIO, IUMan;

    CONST
      ALFALEN = 8;

    TYPE
      Alfa = PACKED ARRAY [1..ALFALEN] OF Char;
      Str80 = String[80];

    VAR
      WhichFile: Str80; {Contains name of intrinsic.lib for compiler to use}

    PROCEDURE IntrinIndirect(VAR IULibIn: Boolean; VAR ThisUnit: Alfa; PROCEDURE
                             ReadIt(FileName: Str80; FLoc: LongInt);
                             VAR FName: Alfa);

  IMPLEMENTATION

    VAR
      FNum, UNum, thisFNum: Integer;
      IULoc: ARRAY [1..MAXUNITS] OF FileAddr;

    PROCEDURE IntrinIndirect{VAR IULibIn: Boolean; VAR ThisUnit: Alfa; PROCEDURE
                             ReadIt(FileName: Str80; FLoc: LongInt); VAR FName:
                             Alfa};

      VAR
        InBlock: ObjBlock;
        UNam: NameString;
        i: Integer;
        OV: ObjVarBlock;
        FL: FileAddr;

      PROCEDURE FindUName(i: Integer);

        VAR
          Found: Boolean;
          j: Integer;

        BEGIN
          Found := True;
          FOR j := 1 TO 8 DO
            IF FName[j] <> IULibUnts[i]^.UnitName[j] THEN Found := False;
          IF Found THEN
            BEGIN
            FNum := IULibUnts[i]^.FileNumber;
            UNum := i;
            END;
        END;

      PROCEDURE FindThis(i: Integer);

        VAR
          Found: Boolean;
          j: Integer;

        BEGIN
          Found := True;
          FOR j := 1 TO 8 DO
            IF ThisUnit[j] <> IULibUnts[i]^.UnitName[j] THEN Found := False;
          IF Found THEN thisFNum := IULibUnts[i]^.FileNumber;
        END;

      PROCEDURE SetFloc(i: Integer);

        VAR
          Found: Boolean;
          j: Integer;

        BEGIN
          IF IULibUnts[i]^.FileNumber = FNum THEN
            BEGIN
            Found := True;
            FOR j := 1 TO 8 DO
              IF UNam[j] <> IULibUnts[i]^.UnitName[j] THEN Found := False;
            IF Found THEN IULoc[i] := FL;
            END;
        END;

      PROCEDURE NoInterfaces(i: Integer);

        BEGIN
          IF IULibUnts[i]^.FileNumber = FNum THEN IULoc[i] := 0;
        END;

      BEGIN
        IF NOT IULibIn THEN
          BEGIN
          InitPasDefs; InitIUMan;
          OpenObjFile(iuLibFile, WhichFile, False);
          IF IOResult <= 0 THEN
            BEGIN
            ReadIULib; IULibIn := True;
            CloseObjFile(iuLibFile, True);
            thisFNum := 0;
            EachIUUnit(FindThis);
            FOR i := 1 TO MAXUNITS DO IULoc[i] := - 1; {Unkn interface Location}
            END;
          END;
        IF IULibIn THEN
          BEGIN
          FNum := 0;
          EachIUUnit(FindUName);
          IF (FNum <> 0) AND (FNum <> thisFNum) THEN
            BEGIN
            IF IULoc[UNum] > 0 THEN
              ReadIt(iuLibStrs[FNum]^, IULoc[UNum])
            ELSE IF IULoc[UNum] = - 1 THEN
              BEGIN
              OpenObjFile(iuLibFile, iuLibStrs[FNum]^, False);
              IF IOResult <= 0 THEN
                BEGIN
                GetObjInvar(iuLibFile, InBlock);
                IF InBlock.blockHeader = VersionCtrl THEN
                  BEGIN
                  REPEAT
                    GetObjInvar(iuLibFile, InBlock)
                  UNTIL (InBlock.blockHeader = InterfLoc) OR
                        (InBlock.blockHeader = ModuleName) OR
                        (InBlock.blockHeader = EOFMark);
                  IF InBlock.blockHeader = InterfLoc THEN
                    BEGIN
                    FOR i := 1 TO InBlock.NrVariants DO
                      BEGIN
                      GetObjVar(iuLibFile, IntfLocVariant, OV);
                      UNam := OV.bIntfLocVariant.UnitName;
                      FL := OV.bIntfLocVariant.IfLoc;
                      EachIUUnit(SetFloc);
                      END;
                    END
                  ELSE
                    EachIUUnit(NoInterfaces); { No InterfLoc block }
                  END
                ELSE
                  FatalError(concat('Bad object file: ', iuLibStrs[FNum]^));
                CloseObjFile(iuLibFile, True);
                END
              ELSE
                EachIUUnit(NoInterfaces); { can't open file. }
              IF IULoc[UNum] > 0 THEN ReadIt(iuLibStrs[FNum]^, IULoc[UNum]);
              END;
            END;
          END;
      END;
END.

