-- Copyright (C) 1983  by Xerox Corporation. All rights reserved. 
-- Indirection.mesa, HGM, 13-Mar-83  9:15:13

DIRECTORY
  CmFile USING [
    Close, Error, FindSection, Handle, NextValue, Open, TableError],
  StringLookUp USING [noMatch, TableDesc],
  Token USING [FreeTokenString, Item],
  Indirect USING [];

Indirection: PROGRAM IMPORTS CmFile, Token EXPORTS Indirect =
  BEGIN

  parmFileName: LONG STRING ← NIL;

  FindOurName: PROCEDURE =
    BEGIN
    cmFile: CmFile.Handle;
    Option: TYPE = MACHINE DEPENDENT{
      parameterFile(0), noMatch(StringLookUp.noMatch)};
    DefinedOption: TYPE = Option [parameterFile..parameterFile];
    CheckType: PROCEDURE [h: CmFile.Handle, table: StringLookUp.TableDesc]
      RETURNS [index: CARDINAL] = CmFile.NextValue;
    MyNextValue: PROCEDURE [
      h: CmFile.Handle,
      table: LONG DESCRIPTOR FOR ARRAY DefinedOption OF LONG STRING]
      RETURNS [index: Option] = LOOPHOLE[CheckType];
    optionTable: ARRAY DefinedOption OF LONG STRING ← [
      parameterFile: "ParameterFile"L];
    cmFile ← CmFile.Open[
      "User.cm"L ! CmFile.Error => BEGIN cmFile ← NIL; CONTINUE; END];
    IF cmFile = NIL THEN RETURN;
    IF ~CmFile.FindSection[cmFile, "Indirect"L] THEN RETURN;
    DO
      option: Option;
      option ← MyNextValue[cmFile, DESCRIPTOR[optionTable] !
        CmFile.TableError => RETRY];
      SELECT option FROM
        noMatch => EXIT;
        parameterFile =>
          BEGIN
          [] ← Token.FreeTokenString[parmFileName];
          parmFileName ← Token.Item[cmFile, FALSE];
          END;
        ENDCASE => ERROR;
      ENDLOOP;
    cmFile ← CmFile.Close[cmFile];
    END;

  GetParmFileName: PUBLIC PROCEDURE RETURNS [LONG STRING] =
    BEGIN RETURN[parmFileName]; END;

  OpenSection: PUBLIC PROCEDURE [section: LONG STRING] RETURNS [cmFile: CmFile.Handle] =
    BEGIN
    cmFile ← CmFile.Open[
      parmFileName ! CmFile.Error => BEGIN cmFile ← NIL; CONTINUE; END];
    IF cmFile = NIL THEN RETURN;
    IF ~CmFile.FindSection[cmFile, section] THEN
      cmFile ← CmFile.Close[cmFile];
    END;

  NextValue: PUBLIC PROCEDURE [h: CmFile.Handle, table: StringLookUp.TableDesc]
    RETURNS [index: CARDINAL] =
      BEGIN
      RETURN[CmFile.NextValue[h, table]];
      END;

  Close: PUBLIC PROCEDURE [cmFile: CmFile.Handle] =
    BEGIN
    [] ← CmFile.Close[cmFile];
    END;

  -- Initialization
  FindOurName[];
  END.