-- MDSubrImpl.Mesa -- last edit January 4, 1983 1:30 pm -- last edit May 22, 1983 4:49 pm, Russ Atkinson -- Pilot 6.0/ Mesa 7.0 DIRECTORY CWF: TYPE USING [FWF0, FWF1, SWF1, SWF2, SWF3, WF0, WF1, WF2], LongString: TYPE USING [EquivalentString], IO: TYPE USING[PutChar], MDSubr: TYPE USING [AddToLook, entNil, Entry, EntrySeq, HUGEDEPLIST, Look, lookNil, LookSeq, LookupOtherSym, SMALLDEPLIST, StringSeq, WalkTheGraph], Stream: TYPE USING [Handle, PutChar], String: TYPE USING [AppendString], Subr: TYPE USING [CopyString, EndsIn, FreeString, PackedTime, strcpy, SubStrCopy, TTYProcs], Time: TYPE USING [Current]; MDSubrImpl: PROGRAM IMPORTS CWF, IO, LongString, MDSubr, Stream, String, Subr, Time EXPORTS MDSubr = { -- no MDS USAGE !!! -- utilities StripFirstWord: PUBLIC PROC[str, result: LONG STRING] = { i: CARDINAL _ 0; WHILE i < str.length AND i = entryseq.maxsize THEN { m: CARDINAL _ entryseq.maxsize; CWF.WF1["Error - too many dependency entries > %d\n"L,@m] } ELSE { -- other fields are defaulted entryseq[entryseq.size] _ [name: Subr.CopyString[name, entryseq.entryzone], depends: DESCRIPTOR[NIL, 0]]; entryseq[entryseq.size].depends _ DESCRIPTOR[entryseq.entryzone.NEW[ ARRAY[0..MDSubr.SMALLDEPLIST) OF CARDINAL], MDSubr.SMALLDEPLIST]; entryseq[entryseq.size].depends[0] _ MDSubr.entNil; entryseq.size _ entryseq.size + 1; }; RETURN[entryseq.size-1,TRUE]; }; AddToDepends: PUBLIC PROC[parent, child: CARDINAL, entryseq: MDSubr.EntrySeq] = { i, max, len, inx: CARDINAL; saved: LONG DESCRIPTOR FOR ARRAY OF CARDINAL; entry: MDSubr.Entry; temp: CARDINAL; p: LONG POINTER; IF parent = MDSubr.entNil THEN RETURN; i _ 0; len _ LENGTH[entryseq[parent].depends]; max _ len - 1; entry _ @entryseq[parent]; WHILE i < max DO inx _ entry.depends[i]; IF inx = child THEN RETURN; -- already there IF inx = MDSubr.entNil THEN EXIT; i _ i + 1; REPEAT FINISHED => { -- CWF.WF1["Extending %s\n"L, entry.name]; IF len >= MDSubr.HUGEDEPLIST THEN { CWF.WF0["Error - too many depends\n"L]; RETURN; }; saved _ entry.depends; p _ entryseq.entryzone.NEW[ARRAY[0..MDSubr.HUGEDEPLIST) OF CARDINAL]; entry.depends _ DESCRIPTOR[p,MDSubr.HUGEDEPLIST]; FOR i IN [0..LENGTH[saved]) DO temp _ saved[i]; entry.depends[i] _ temp; ENDLOOP; i _ max; p _ BASE[saved]; -- no frees allowed -- longzone.FREE[@p]; }; ENDLOOP; entry.depends[i] _ child; entry.depends[i+1] _ MDSubr.entNil; }; FreeEntrySeq: PUBLIC PROC[pentryseq: LONG POINTER TO MDSubr.EntrySeq] = { entry: MDSubr.Entry; longp: LONG POINTER; IF pentryseq^ = NIL THEN RETURN; IF FALSE THEN -- no frees allowed FOR i: CARDINAL IN [0..pentryseq^.size) DO entry _ @(pentryseq^)[i]; Subr.FreeString[entry.name]; Subr.FreeString[entry.rule]; longp _ BASE[entry.depends]; -- IF longp ~= NIL THEN longzone.FREE[@longp]; entry^ _ [depends: DESCRIPTOR[NIL,0]]; ENDLOOP; -- longzone.FREE[pentryseq]; pentryseq^ _ NIL; }; -- proc is only called once for each node that is connected to firstinx WalkTheGraph: PUBLIC PROC[firstinx: CARDINAL, entryseq:MDSubr.EntrySeq, proc: PROC[MDSubr.Entry]] = { RecurseThru: PROC[inx: CARDINAL, entryseq:MDSubr.EntrySeq, proc: PROC[MDSubr.Entry]] = { i: CARDINAL; entry: MDSubr.Entry _ @entryseq[inx]; IF entry.visited THEN RETURN; proc[entry]; -- call the users proc entry.visited _ TRUE; i _ 0; WHILE entry.depends[i] ~= MDSubr.entNil DO -- the recursive call RecurseThru[entry.depends[i], entryseq, proc]; i _ i + 1; ENDLOOP; }; FOR i: CARDINAL IN [0 .. entryseq.size) DO entryseq[i].visited _ FALSE; ENDLOOP; RecurseThru[firstinx, entryseq, proc]; }; -- look for a specific case of a .bcd depending on both a .config -- and .mesa file ThrowAwayLeaves: PUBLIC PROC[firstinx: CARDINAL, entryseq: MDSubr.EntrySeq, lookseq: MDSubr.LookSeq, ismodel: BOOL] = { RecurThrowAwayLeaves: PROC[entry: MDSubr.Entry] = { i, j1, j2: CARDINAL; lookj1, lookj2: MDSubr.Look; IF ismodel AND Subr.EndsIn[entry.name, ".bcd"L] THEN { i _ 0; lookj1 _ NIL; WHILE (j1 _ entry.depends[i]) ~= MDSubr.entNil DO IF (Subr.EndsIn[entryseq[j1].name,".config"L] OR Subr.EndsIn[entryseq[j1].name, ".mesa"L]) THEN { lookj1 _ @lookseq[entryseq[j1].lookinx]; IF lookj1.presentonlocaldisk THEN RETURN; }; i _ i + 1; ENDLOOP; -- if there was a .mesa or .config, and not on disk, then -- throw out IF lookj1 ~= NIL THEN { entry.depends[0] _ MDSubr.entNil; entry.rule _ NIL }; } ELSE { IF Subr.EndsIn[entry.name, ".bcd"L] AND (j1 _ entry.depends[0]) ~= MDSubr.entNil AND (j2 _ entry.depends[1]) ~= MDSubr.entNil AND entry.depends[2] = MDSubr.entNil AND Subr.EndsIn[entryseq[j1].name,".config"L] AND Subr.EndsIn[entryseq[j2].name, ".mesa"L] THEN { lookj1 _ @lookseq[entryseq[j1].lookinx]; lookj2 _ @lookseq[entryseq[j2].lookinx]; IF NOT lookj1.presentonlocaldisk AND NOT lookj2.presentonlocaldisk THEN entry.depends[0] _ MDSubr.entNil ELSE IF lookj1.presentonlocaldisk AND NOT lookj2.presentonlocaldisk THEN entry.depends[1] _ MDSubr.entNil ELSE IF NOT lookj1.presentonlocaldisk AND lookj2.presentonlocaldisk THEN { entry.depends[0] _ j2; entry.depends[1] _ MDSubr.entNil }; }; }; }; FOR i: CARDINAL IN [0.. entryseq.size) DO entryseq[i].visited _ FALSE; ENDLOOP; MDSubr.WalkTheGraph[firstinx, entryseq, RecurThrowAwayLeaves]; }; CheckNames: PUBLIC PROC[entryseq: MDSubr.EntrySeq, lookseq: MDSubr.LookSeq] = { look: MDSubr.Look; header: BOOL _ FALSE; FOR i: CARDINAL IN [0..entryseq.size) DO IF entryseq[i].lookinx ~= MDSubr.lookNil THEN { look _ @lookseq[entryseq[i].lookinx]; IF NOT LongString.EquivalentString[look.name, entryseq[i].name] THEN { IF NOT header THEN { CWF.WF0["Errors in look vs entry:\n"L]; header _ TRUE; }; CWF.WF2["Err - look %s entry %s\n"L, look.name, entryseq[i].name]; }; }; ENDLOOP; -- CWF.WF0["Looks ok to me\n"L]; }; ConvertToLook: PUBLIC PROC[entryseq: MDSubr.EntrySeq, lookseq: MDSubr.LookSeq] = { FOR i: CARDINAL IN [0..entryseq.size) DO IF entryseq[i].lookinx = MDSubr.lookNil THEN { entryseq[i].lookinx _ lookseq.size; [] _ MDSubr.AddToLook[entryseq[i].name, lookseq]; }; ENDLOOP; }; InsertOtherSym: PUBLIC PROC[str, val: LONG STRING, stringseq: MDSubr.StringSeq] = { IF stringseq.size >= stringseq.maxsize THEN CWF.WF0["too many other syms\n"L] ELSE { stringseq[stringseq.size].str _ Subr.CopyString[str]; stringseq[stringseq.size].val _ Subr.CopyString[val]; stringseq.size _ stringseq.size + 1; }; RETURN; }; -- return the value corresponding to "str" -- searches backwards to allow users to redefine the strings LookupOtherSym: PUBLIC PROC[str: LONG STRING, stringseq: MDSubr.StringSeq] RETURNS[LONG STRING] = { FOR i: CARDINAL DECREASING IN [0..stringseq.size) DO IF LongString.EquivalentString[str,stringseq[i].str] THEN RETURN[stringseq[i].val]; ENDLOOP; RETURN[NIL]; }; GetCompilerRule: PUBLIC PROC[stringseq: MDSubr.StringSeq, name: LONG STRING, zone: UNCOUNTED ZONE] RETURNS[LONG STRING] = { comprule: STRING _ [100]; str: LONG STRING; pat: STRING _ [100]; count: CARDINAL _ 0; str _ MDSubr.LookupOtherSym["PILOTMESACOMP"L, stringseq]; IF str = NIL THEN str _ MDSubr.LookupOtherSym["MESACOMP"L, stringseq]; Subr.strcpy[pat, str]; FOR i: CARDINAL IN [0..pat.length) DO IF pat[i] = '% THEN count _ count + 1; ENDLOOP; IF count = 0 THEN String.AppendString[pat, " %s"L]; IF count > 3 THEN CWF.WF1["Too many %% in '%s'\n"L, pat] ELSE IF count = 3 THEN CWF.SWF3[comprule, pat, name, name, name] ELSE IF count = 2 THEN CWF.SWF2[comprule, pat, name, name] ELSE CWF.SWF1[comprule, pat, name]; RETURN[Subr.CopyString[comprule, zone]]; }; GetBinderRule: PUBLIC PROC[stringseq: MDSubr.StringSeq, name: LONG STRING, zone: UNCOUNTED ZONE] RETURNS[LONG STRING] = { comprule: STRING _ [100]; str: LONG STRING; pat: STRING _ [100]; count: CARDINAL _ 0; i: CARDINAL; str _ MDSubr.LookupOtherSym["PILOTMESABIND"L, stringseq]; IF str = NIL THEN str _ MDSubr.LookupOtherSym["MESABIND"L, stringseq]; Subr.strcpy[pat, str]; FOR i IN [0..pat.length) DO IF pat[i] = '% THEN count _ count + 1; ENDLOOP; IF count = 0 THEN String.AppendString[pat, " %s"L]; IF count > 3 THEN CWF.WF1["Too many %% in '%s'\n"L, pat] ELSE IF count = 3 THEN CWF.SWF3[comprule, pat, name, name, name] ELSE IF count = 2 THEN CWF.SWF2[comprule, pat, name, name] ELSE CWF.SWF1[comprule, pat, name]; RETURN[Subr.CopyString[comprule, zone]]; }; }. IDEAS 1. comments in line.cm for error messages