DIRECTORY Basics USING [CompareInt, Comparison], Commander USING [CommandProc, Register], IO USING [BreakProc, card, Close, EndOf, GetLineRope, GetTokenRope, PutF, RIS, rope, STREAM], FS USING [StreamOpen], List USING [Compare, CompareProc, Comparison, LORA, Merge, Sort], Rope USING [Cat, Compare, Equal, Fetch, Length, ROPE, Substr], SymTab USING [Create, Fetch, EachPairAction, Pairs, Ref, Store]; ExpertPartList: CEDAR PROGRAM IMPORTS Basics, Commander, List, FS, IO, Rope, SymTab = BEGIN ROPE: TYPE = Rope.ROPE; Entry: TYPE = REF EntryRep; EntryRep: TYPE = RECORD [ refDes: ROPE, part: ROPE ]; PartTable: TYPE = SymTab.Ref; RefDesList: TYPE = List.LORA; TokenProc1: IO.BreakProc ~ { -- Takes any character different from SP for the name IF char = ' THEN RETURN [sepr]; RETURN [other]; }; Compare: List.CompareProc ~ { comp: List.Comparison; x1, x2, mul: INT; r1, r2: ROPE; len1, len2: INT; IF ISTYPE[ref1, Entry] THEN { entry1: Entry _ NARROW[ref1]; entry2: Entry _ NARROW[ref2]; RETURN Compare[entry1.refDes, entry2.refDes]; }; r1 _ NARROW[ref1]; r2 _ NARROW[ref2]; len1 _ Rope.Length[r1]; len2 _ Rope.Length[r2]; x1 _ 0; mul _ 1; WHILE len1 # 0 AND '0 <= Rope.Fetch[r1, len1-1] AND Rope.Fetch[r1, len1-1] <= '9 DO x1 _ x1 + mul * (Rope.Fetch[r1, len1-1] - '0); len1 _ len1 - 1; mul _ mul * 10; ENDLOOP; x2 _ 0; mul _ 1; WHILE len2 # 0 AND '0 <= Rope.Fetch[r2, len2-1] AND Rope.Fetch[r2, len2-1] <= '9 DO x2 _ x2 + mul * (Rope.Fetch[r2, len2-1] - '0); len2 _ len2 - 1; mul _ mul * 10; ENDLOOP; r1 _ Rope.Substr[r1, 0, len1]; r2 _ Rope.Substr[r2, 0, len2]; comp _ Rope.Compare[r1, r2, FALSE]; IF comp # equal THEN RETURN Rope.Compare[r1, r2, FALSE]; RETURN Basics.CompareInt[x1, x2]; }; IsNext: PROC [r1, r2: ROPE] RETURNS [next: BOOL _ FALSE] ~ { comp: List.Comparison; x1, x2, mul: INT; len1: INT _ Rope.Length[r1]; len2: INT _ Rope.Length[r2]; x1 _ 0; mul _ 1; WHILE len1 # 0 AND '0 <= Rope.Fetch[r1, len1-1] AND Rope.Fetch[r1, len1-1] <= '9 DO x1 _ x1 + mul * (Rope.Fetch[r1, len1-1] - '0); len1 _ len1 - 1; mul _ mul * 10; ENDLOOP; x2 _ 0; mul _ 1; WHILE len2 # 0 AND '0 <= Rope.Fetch[r2, len2-1] AND Rope.Fetch[r2, len2-1] <= '9 DO x2 _ x2 + mul * (Rope.Fetch[r2, len2-1] - '0); len2 _ len2 - 1; mul _ mul * 10; ENDLOOP; r1 _ Rope.Substr[r1, 0, len1]; r2 _ Rope.Substr[r2, 0, len2]; comp _ Rope.Compare[r1, r2, FALSE]; IF comp # equal THEN RETURN; IF (x1 + 1) = x2 THEN next _ TRUE; }; ProcessEachLine: PROC [partTable: PartTable, line: ROPE] RETURNS [entry: Entry] ~ { refDes, key: ROPE; x, refDesList, newRefDesList: RefDesList; in: IO.STREAM _ IO.RIS[line]; refDes _ IO.GetTokenRope[in, TokenProc1].token; key _ IO.GetTokenRope[in, TokenProc1].token; x _ CONS[refDes, NIL]; refDesList _ NIL; IF SymTab.Fetch[partTable, key].found THEN { refDesList _ NARROW[SymTab.Fetch[partTable, key].val]; }; newRefDesList _ List.Merge[x, refDesList, Compare]; [] _ SymTab.Store[partTable, key, newRefDesList]; entry _ NEW[EntryRep]; entry.refDes _ refDes; entry.part _ key; }; ReadPartFile: PROC [file: ROPE] RETURNS [partTable: PartTable, completeEntryList: List.LORA] ~ { x: List.LORA; r: Entry; line: ROPE; exit: BOOLEAN _ FALSE; in: IO.STREAM _ FS.StreamOpen[file]; partTable _ SymTab.Create[]; x _ NIL; WHILE NOT IO.EndOf[in] DO line _ IO.GetLineRope[in]; r _ ProcessEachLine[partTable, line]; x _ CONS[r, x]; ENDLOOP; completeEntryList _ List.Sort[x, Compare]; }; PrintEachEntry: PROC [out: IO.STREAM, entry: ROPE, refDesList:List.LORA] ~ { i, j: CARD _ 0; r, r1, r2, r3: ROPE _ NIL; FOR l: List.LORA _ refDesList, l.rest UNTIL l = NIL DO i _ i + 1; r3 _ NARROW[l.first]; IF IsNext[r2, r3] THEN { r2 _ r3; LOOP; }; IF r1 # NIL THEN { IF (j MOD 5) = 0 THEN r _ Rope.Cat[r, "\n\t\t"]; IF Rope.Equal[r1, r2] THEN r _ Rope.Cat[r, r1, "\t"] ELSE IF IsNext[r1, r2] THEN r _ Rope.Cat[r, r1, "\t", r2 ,"\t"] ELSE r _ Rope.Cat[r, r1, "-", r2 ,"\t"]; j _ j + 1; }; r1 _ r3; r2 _ r3; ENDLOOP; IF r1 # NIL THEN { IF (j MOD 5) = 0 THEN r _ Rope.Cat[r, "\n\t\t"]; IF Rope.Equal[r1, r2] THEN r _ Rope.Cat[r, r1, "\t"] ELSE IF IsNext[r1, r2] THEN r _ Rope.Cat[r, r1, "\t", r2 ,"\t"] ELSE r _ Rope.Cat[r, r1, "-", r2 ,"\t"]; }; IO.PutF[out, "%g\t%g%g\n\n", IO.rope[entry], IO.card[i], IO.rope[r]]; }; ExpertPartListProc: Commander.CommandProc = BEGIN SortEachEntry: SymTab.EachPairAction ~ { x: List.LORA _ CONS[key, NIL]; sortedPartList _ List.Merge[x, sortedPartList, Compare]; }; totalNumberOfParts: CARD; partTable: PartTable; completeEntryList: List.LORA; sortedPartList: List.LORA; savedRefDes1, savedRefDes2, savedPart: ROPE; stream: IO.STREAM _ IO.RIS[cmd.commandLine]; name: ROPE _ IO.GetTokenRope[stream].token; partlistName: ROPE _ Rope.Cat[name, ".partlist"]; newpartlistName: ROPE _ Rope.Cat[name, ".newnewpartlist"]; out: IO.STREAM _ FS.StreamOpen[newpartlistName, $create]; IO.PutF[cmd.out, "Reading %g\n", IO.rope[partlistName]]; [partTable, completeEntryList] _ ReadPartFile[partlistName]; IO.PutF[cmd.out, "Writing %g\n", IO.rope[newpartlistName]]; IO.PutF[out, "Partlist sorted by reference designators\n\n"]; savedPart _ NIL; totalNumberOfParts _ 0; FOR l: List.LORA _ completeEntryList, l.rest UNTIL l = NIL DO entry: Entry _ NARROW[l.first]; totalNumberOfParts _ totalNumberOfParts + 1; IF Rope.Equal[entry.part, savedPart] AND IsNext[savedRefDes2, entry.refDes] THEN { savedRefDes2 _ entry.refDes; } ELSE { IF savedPart # NIL THEN { IF Rope.Equal[savedRefDes1, savedRefDes2] THEN { IO.PutF[out, "%g\t\t%g\n", IO.rope[savedRefDes1], IO.rope[savedPart]]; } ELSE { IO.PutF[out, "%g-%g\t%g\n", IO.rope[savedRefDes1], IO.rope[savedRefDes2], IO.rope[savedPart]]; }; }; savedRefDes1 _ entry.refDes; savedRefDes2 _ entry.refDes; savedPart _ entry.part; }; ENDLOOP; IF Rope.Equal[savedRefDes1, savedRefDes2] THEN { IO.PutF[out, "%g\t%g\n", IO.rope[savedRefDes1], IO.rope[savedPart]]; } ELSE { IO.PutF[out, "%g to %g\t%g\n", IO.rope[savedRefDes1], IO.rope[savedRefDes2], IO.rope[savedPart]]; }; IO.PutF[out, "\n\nPartlist sorted by part type\n\n"]; IO.PutF[cmd.out, "Total number of parts: %g\n", IO.card[totalNumberOfParts]]; sortedPartList _ NIL; [] _ SymTab.Pairs[partTable, SortEachEntry]; totalNumberOfParts _ 0; FOR l: List.LORA _ sortedPartList, l.rest UNTIL l = NIL DO totalNumberOfParts _ totalNumberOfParts + 1; PrintEachEntry[out, NARROW[l.first], NARROW[SymTab.Fetch[partTable, NARROW[l.first]].val]]; ENDLOOP; IO.Close[out]; IO.PutF[cmd.out, "Number of different parts: %g\n", IO.card[totalNumberOfParts]]; END; Commander.Register[ key: "ExpertPartList", proc: ExpertPartListProc, doc: "Read a .pcb and a .lib file and generates a .partlist file\n"]; END. `ExpertPartList.mesa Christophe Cuenod April 7, 1989 2:32:08 pm PDT Reads a .partlist file and generates a .newpartlist file ReadPartFile: PROC [file: ROPE] RETURNS [partTable: PartTable, completeRefDesList: RefDesList] ~ { x: RefDesList; r: Entry; line, spareLine: ROPE; exit: BOOLEAN _ FALSE; in: IO.STREAM _ FS.StreamOpen[file]; partTable _ SymTab.Create[]; line _ IO.GetLineRope[in]; x _ NIL; WHILE NOT IO.EndOf[in] AND line # NIL DO spareLine _ IO.GetLineRope[in]; r _ ProcessEachLine[partTable, line]; x _ CONS[r, x]; line _ spareLine; ENDLOOP; completeRefDesList _ List.Sort[x, Compare]; }; Κ !–i(firstHeadersAfterPage) {1} .cvx .def (firstPageNumber) {1} .cvx .def (oneSidedFormat) {.false} .cvx .def– "Cedar" style˜– "Cedar" stylešœ™Icodešœ.™.—J™Iunit™8šΟk ˜ Kšœœ˜&Kšœ œ˜(KšœœBœœ˜]Kšœœ˜Kšœœ$œ˜AKšœœ&œ ˜>Kšœœ4˜@—šΟnœœ˜Kšœœœ˜8—Lš˜Lšœœœ˜Lšœœ˜šœ œœ˜Lšœœ˜ Lšœ˜ L˜—Kšœ œ˜Kšœ œœ˜K– "cedar" style˜šž œœΟc5˜RKšœ œœ˜!Kšœ ˜K˜—šžœ˜Kšœ˜Kšœ œ˜Kšœœ˜ Kšœ œ˜šœœœ˜Kšœœ˜Kšœœ˜Kšœ'˜-K˜—Kšœœ˜Kšœœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜šœ œœ˜SKšœ.˜.Kšœ˜K˜Kšœ˜—Kšœ˜Kšœ˜šœ œœ˜SKšœ.˜.Kšœ˜K˜Kšœ˜—Kšœ˜Kšœ˜Kšœœ˜#Kšœœœœ˜8Kšœ˜"K˜—š žœœ œœœœ˜