<> <> <> <<>> <<>> DIRECTORY CD, CDRepetitions, CDCommandOps, CDDirectory, CDOps, CDSequencer, IO, Rope, TerminalIO; RepHacks: CEDAR PROGRAM IMPORTS CDRepetitions, CDCommandOps, CDDirectory, CDOps, IO, Rope, TerminalIO ~ BEGIN hackMenu: ATOM _ $SpecialMenu; -- where DAUserHacks commands are forcefully registered ROPE: TYPE = Rope.ROPE; <> <> CheckReps: PROC [comm: CDSequencer.Command] ~ { EachObject: PROC [me: CD.Object, data: REF_NIL] RETURNS [quit: BOOL_FALSE] ~ { IF ~CDRepetitions.IsRepetition[me] THEN RETURN; TerminalIO.PutF["Yep!\n"]; quit _ TRUE; }; inst: CD.Instance; multiple: BOOL; [inst, multiple] _ CDOps.SelectedInstance[comm.design]; IF multiple THEN {TerminalIO.PutF["Multiple Selections\n"]; RETURN}; IF ~CDDirectory.EnumerateObject[ob: inst.ob, proc: EachObject] THEN TerminalIO.PutF["Nope!\n"]; }; <> <> nameMagicCounter: NAT _ 0; NewName: PROC [] RETURNS [name: ROPE] ~ { -- Generates a new name on every call nameMagicCounter _ nameMagicCounter+1; name _ IO.PutFR["NEWCELLN%g", IO.int[nameMagicCounter]]; }; IsLowerC: PROC [c: CHAR] RETURNS [BOOL] ~ {RETURN [c IN ['a..'z]]}; IsUpperC: PROC [c: CHAR] RETURNS [BOOL] ~ {RETURN [c IN ['A..'Z]]}; IsLetter: PROC [c: CHAR] RETURNS [BOOL] ~ {RETURN [(c IN ['A..'Z]) OR (c IN ['a..'z])]}; IsDigit: PROC [c: CHAR] RETURNS [BOOL] ~ {RETURN [(c IN ['0..'9])]}; Sanitize: PROC [old: CHAR] RETURNS [new: CHAR] ~ { -- Replaces funny characters by x's new _ SELECT TRUE FROM IsLowerC[old] => old+('A-'a), IsUpperC[old] => old, IsDigit[old] => old, ENDCASE => 'X; }; SanitizeName: PROC [name: ROPE] RETURNS [simpler: ROPE] ~ { IF Rope.IsEmpty[name] OR Rope.Length[name]>16 THEN RETURN[NewName[]]; simpler _ Rope.Translate[base: name, translator: Sanitize]; IF IsDigit[Rope.Fetch[simpler, 0]] THEN simpler _ Rope.Cat["X", simpler]; IF Rope.Length[simpler]>16 THEN TerminalIO.PutF["%g has more than 16 characters\n", IO.rope[simpler]]; }; SanitizeDesign: PROC [comm: CDSequencer.Command] ~ { EachObject: PROC [name: ROPE, ob: CD.Object] RETURNS [quit: BOOL_FALSE] ~ { safe: NAT _ 0; newName: ROPE _ SanitizeName[name]; IF Rope.Equal[name, newName] THEN RETURN; TerminalIO.PutF["%g -> %g\n", IO.rope[name], IO.rope[newName]]; IF CDDirectory.Rename[design: comm.design, object: ob, newName: newName, fiddle: FALSE, fiddleFirst: FALSE, removeFirst: FALSE].done THEN RETURN; DO newName _ NewName[]; -- it failed for some reason: try again! TerminalIO.PutF["%g -> %g, another try\n", IO.rope[name], IO.rope[newName]]; IF CDDirectory.Rename[design: comm.design, object: ob, newName: newName, fiddle: FALSE, fiddleFirst: FALSE, removeFirst: FALSE].done THEN EXIT; <<-- something is very screwed up here!>> safe _ safe+1; IF safe>100 THEN ERROR; ENDLOOP; }; TerminalIO.PutF["Sanitizing the name of all cells in the directory\n"]; [] _ CDDirectory.Enumerate[design: comm.design, action: EachObject]; TerminalIO.PutF["Yep, that's what it takes to interface to the real world!\n"]; }; <> <> <> <> <> <maxDepth THEN maxDepth _ d;>> <> <<};>> <> <> <<[inst, multiple] _ CDOps.SelectedInstance[comm.design];>> <> <<[] _ CDDirectory.EnumerateObject[ob: inst.ob, proc: EachObject, data: NEW[NAT _ depth], recurse: FALSE];>> <> <<};>> <<>> <> CDCommandOps.RegisterWithMenu[hackMenu, "Check for reps", "Check if contains a CD repetition", $RepHacksCheckReps, CheckReps]; CDCommandOps.RegisterWithMenu[hackMenu, "Sanitize cell names", "Makes all cell names acceptable to almost any brain-damaged aging software", $RepHacksSanitize, SanitizeDesign]; <> END.