-- NameImpl.Mesa  Edited by: Johnsson  July 18, 1980  10:43 AM

DIRECTORY
  BcdDefs USING [MTIndex],
  BcdOps USING [BcdBase, MTHandle, NameString, ProcessModules],
  DebugUsefulDefs USING [UserAborted],
  DLoadState USING [Acquire, AcquireBcd, MapRealToConfig, ReleaseBcd, Release],
  Strings USING [AppendSubString, SubStringDescriptor],
  Frames USING [Invalid],
  Gf USING [GFI, Handle, Original],
  MachineDefs USING [ConfigIndex, GFHandle, GFTIndex, NullConfig],
  UserInput USING [userAbort];

NameImpl: PROGRAM
  IMPORTS
    BcdOps, DebugUsefulDefs, Strings, Frames, Gf, DLoadState, UserInput
  EXPORTS DebugUsefulDefs =
  BEGIN OPEN Gf, MachineDefs;

  Name: PUBLIC PROCEDURE [name: STRING, gf: MachineDefs.GFHandle ← NIL] =
    BEGIN
    config: ConfigIndex;
    cgfi: GFTIndex;
    ssb: BcdOps.NameString;
    bcd: BcdOps.BcdBase;

      FindModule: PROC [mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOLEAN] =
	BEGIN
	ssd: Strings.SubStringDescriptor;
	IF cgfi IN [mth.gfi..mth.gfi+mth.ngfi) THEN {
	  ssd ← [base: @ssb.string, offset: mth.name, length: ssb.size[mth.name]];
	  Strings.AppendSubString[name, @ssd];
	  RETURN[TRUE]};
	IF UserInput.userAbort THEN SIGNAL DebugUsefulDefs.UserAborted;
	RETURN[FALSE]
	END;

    [] ← DLoadState.Acquire[];
    [cgfi,config] ← DLoadState.MapRealToConfig[Gf.GFI[Gf.Original[gf]]];
    IF config = NullConfig THEN {
      DLoadState.Release[]; ERROR Frames.Invalid[gf]};
    bcd ← DLoadState.AcquireBcd[config];
    ssb ← LOOPHOLE[bcd+bcd.ssOffset];
    [] ← BcdOps.ProcessModules[bcd, FindModule ! UNWIND => Cleanup[bcd]];
    Cleanup[bcd];
    END;
  
  Cleanup: PROC [bcd: BcdOps.BcdBase] =
    {DLoadState.ReleaseBcd[bcd]; DLoadState.Release[]};

  END.