(*****************************************************************************)
(*                           File: PAS/OBJINTER.TEXT                         *)
(*                   (C) Copyright 1983, 1984  Apple Computer, Inc.          *)
(*                            All rights reserved.                           *)
(*                                                                 11-Jan-84 *)
(* 11-Jan-84 Converted to Spring Release IUMan Data Structures               *)
(* 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 StdUnit, 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 IPasDefs;

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

  IMPLEMENTATION

    CONST
      MAXUNITS = 128; {true for old, i.e. non S & E architecture}

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

    PROCEDURE IPasDefs;

      BEGIN {IPasDefs}
        InitPasDefs; {hide this name behind IPasDefs }
      END; {IPasDefs}

    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 {FindUName}
          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; {FindUName}

      PROCEDURE FindThis(i: Integer);

        VAR
          Found: Boolean;
          j: Integer;

        BEGIN {FindThis}
          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; {FindThis}

      PROCEDURE SetFloc(i: Integer);

        VAR
          Found: Boolean;
          j: Integer;

        BEGIN {SetFloc}
          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; {SetFloc}

      PROCEDURE NoInterfaces(i: Integer);

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

      BEGIN {IntrinIndirect}
        IF NOT IULibIn THEN
          BEGIN
          InitPasDefs;
          InitIUMan; OIAllowAbort := False; {shut Steve up!!!}
          OpenObjFile(iuLibFile, WhichFile, False);
          IF IOResult <= 0 THEN
            BEGIN
            IF ReadIULib(False, True, False, NIL) THEN
              BEGIN
              IULibIn := True;
              ThisFNum := 0;
              EachIUUnit(FindThis);
              FOR i := 1 TO MAXUNITS DO IULoc[i] := - 1; {Unkn interface Location}
              END;
            CloseObjFile(iuLibFile, True);
            END;
          END;
        IF IULibIn THEN
          BEGIN
          FNum := 0;
          EachIUUnit(FindUName);
          IF (FNum <> 0) AND (FNum <> ThisFNum) THEN
            BEGIN
            IF IULoc[UNum] > 0 THEN
              ReadIt(IULibFNam^[FNum]^, IULoc[UNum])
            ELSE IF IULoc[UNum] = - 1 THEN
              BEGIN
              OpenObjFile(iuLibFile, IULibFNam^[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: ', IULibFNam^[FNum]^));
                CloseObjFile(iuLibFile, True);
                END
              ELSE
                EachIUUnit(NoInterfaces); {can't open file.}
              IF IULoc[UNum] > 0 THEN ReadIt(IULibFNam^[FNum]^, IULoc[UNum]);
              END;
            END;
          END;
      END; {IntrinIndirect}
END.

