-- ChipAppendNames.mesa

-- Subroutines to append the names of various things to
-- strings.

-- last modified by E. McCreight, July 16, 1982  12:03 PM
-- written by E. McCreight, November 3, 1981  3:06 PM

DIRECTORY
  ChipNetDefs,
  ChipUserInt,
  InlineDefs,
  ppdddefs,
  ppdefs,
  StringDefs;

ChipAppendNames: PROGRAM
  IMPORTS ChipNetDefs, ChipUserInt, InlineDefs,
    ppdddefs, ppdefs, StringDefs
  EXPORTS ChipNetDefs =
  BEGIN OPEN ppdddefs, ppdefs, ChipNetDefs;


  AppendNet: PUBLIC PROCEDURE[s: STRING, net: netPtr]
    RETURNS[cn: CanonNetPtr] =
    BEGIN OPEN StringDefs;
    cn ← CanonNet[net];
    WITH did: (cn ← CanonNet[net]).id SELECT FROM
      normal => AppendNetId[s, @did];
      ENDCASE => ChipUserInt.Explain["Extractor bug - bogus net"];
    END;


  nextNumericNet: locNum ← 1;

  AppendNetId: PUBLIC PROCEDURE[s: STRING,
    netId: NormalNetIdPtr] =
    BEGIN OPEN StringDefs;
    IF netId.nameClass=anonymous THEN
      BEGIN
      netId.name ← numeric[n: nextNumericNet];
      nextNumericNet ← nextNumericNet+1;
      END;

    WITH dn: netId SELECT FROM
      numeric => {AppendChar[s, 'N]; AppendCard[s, dn.n]};
      qualified => AppendTerminalName[s, [dn.source, dn.see]];
      ENDCASE;
    END; -- of AppendNetId


  AppendTerminalName: PUBLIC PROCEDURE[s: STRING,
    c: ItemRef] =
    BEGIN OPEN StringDefs;
    oldLen: CARDINAL ← s.length;
    AppendCallerChain[s, c.head];
    IF s.length>oldLen THEN AppendChar[s, '.];
    AppendString[s, getTextProp[ItemRefToLp[c]].s];
    END; -- of AppendTerminalName


  AppendCallerChain: PUBLIC PROCEDURE[s: STRING,
    c: InstancePtr] =
    BEGIN OPEN StringDefs;
    IF c.caller.head#NIL THEN
      BEGIN
      oldLen: CARDINAL ← s.length;
      AppendCallerChain[s, c.caller.head];
      IF s.length>oldLen THEN AppendChar[s, '.];
      AppendCallerLink[s, c];
      END;
    END; -- of AppendCallerChain


  AppendCallerLink: PUBLIC PROCEDURE[s: STRING,
    c: InstancePtr] =
    BEGIN OPEN StringDefs;
    tp: LONG POINTER TO text prop ← NIL;
    lp: listPtr ← ItemRefToLp[c.caller];
    i: CARDINAL ← 1;
    tp ← getTextProp[lp];
    IF tp#NIL THEN AppendString[s, tp.s]
        -- assumes instances are named uniquely
    ELSE -- anonymous instance
      BEGIN
      WITH dob: lp.ob SELECT FROM
        cell =>
          BEGIN
          sameCellCnt: CARDINAL ← 0;
          IF c.proto.name#NIL THEN
            AppendString[s, c.proto.name]
          ELSE
            BEGIN
            cellNo: CARDINAL ← 1;
            AppendString[s, "AnonCell"];
            FOR ob: LONG POINTER TO cell object ←
              GetCellSuper[], ob.super
              WHILE ob#lp.ob AND ob#NIL DO
              cellNo ← cellNo+1;
              ENDLOOP;
            AppendCard[s, cellNo];
            END;
          FOR lpp: listPtr ← c.caller.head.proto.lp, lpp.nxt
            WHILE lpp#NIL DO
            IF lpp.ob=lp.ob THEN
              BEGIN
              sameCellCnt ← sameCellCnt+1;
              IF (lpp.lx<lp.lx OR (lpp.lx=lp.lx AND lpp.ly<lp.ly))
                THEN i ← i+1;
              END;
            ENDLOOP;
          IF sameCellCnt>1 THEN
            {AppendChar[s, '#]; AppendCard[s, i]};
          END;
        xstr =>
          BEGIN
          AppendString[s, "Q"];
          FOR lpp: listPtr ← c.caller.head.proto.lp, lpp.nxt
            WHILE lpp#NIL DO
            IF lpp.ob.otyp=xstr AND
              (lpp.lx<lp.lx OR (lpp.lx=lp.lx AND lpp.ly<lp.ly))
              THEN i ← i+1;
            ENDLOOP;
          AppendCard[s, i];
          END;
        cont =>
          BEGIN
          AppendString[s, "J"];
          FOR lpp: listPtr ← c.caller.head.proto.lp, lpp.nxt
            WHILE lpp#NIL DO
            IF lpp.ob.otyp=cont AND
              (lpp.lx<lp.lx OR (lpp.lx=lp.lx AND lpp.ly<lp.ly))
              THEN i ← i+1;
            ENDLOOP;
          AppendCard[s, i];
          END;
        bus =>
          BEGIN
          AppendString[s, "Bus"];
          FOR lpp: listPtr ← c.caller.head.proto.lp, lpp.nxt
            WHILE lpp#NIL DO
            IF lpp.ob.otyp=bus AND
              (lpp.lx<lp.lx OR (lpp.lx=lp.lx AND lpp.ly<lp.ly))
              THEN i ← i+1;
            ENDLOOP;
          AppendCard[s, i];
          END;
        ENDCASE => NULL;
      END;
    END; -- of AppendCallerLink


  AppendLocNum: PUBLIC PROCEDURE[s: STRING, n: locNum] =
    BEGIN OPEN StringDefs;
    AppendChar[s, ' ];
    IF n<0 THEN {AppendChar[s, '-]; n ← -n};
    AppendCard[s, n/Lambda];
    END;

  AppendCoord: PUBLIC PROCEDURE[s: STRING, n: Coord] =
    BEGIN OPEN StringDefs;
    AppendChar[s, ' ];
    IF n<0 THEN {AppendChar[s, '-]; n ← -n};
    AppendCard[s, n];
    END;

  AppendCard: PUBLIC PROCEDURE[s: STRING,
    n: LONG CARDINAL] =
    BEGIN OPEN StringDefs;
    IF n>9 THEN {AppendCard[s, n/10]; n ← n MOD 10};
    AppendChar[s, '0+InlineDefs.LowHalf[n]];
    END;

  END. -- of ChipAppendNames