<> <> <> <> <<>> DIRECTORY BitTableLookup, Commander, CommandTool, FS, IO, MessageWindow, PhoneList, PrincOpsUtils, Process, Rope, SpellingCorrection, SymTab, UserProfile; PhoneListImpl: CEDAR MONITOR IMPORTS BitTableLookup, Commander, CommandTool, FS, IO, MessageWindow, PrincOpsUtils, Process, Rope, SpellingCorrection, SymTab, UserProfile EXPORTS PhoneList ~ BEGIN ROPE: TYPE ~ Rope.ROPE; <> phoneList: SymTab.Ref _ NIL; --This is the monitored data phoneListUPEntry: ROPE _ NIL; ExtractNames: PROC [line: ROPE, action: PROC [ROPE]] ~ { Break: IO.BreakProc = { <<[char: CHAR] RETURNS [IO.CharClass]>> RETURN [SELECT char FROM IN ['a..'z], IN ['A..'Z] => other, ENDCASE => sepr]; }; ris: IO.STREAM ~ IO.RIS[rope: line]; DO { rope: ROPE _ IO.GetTokenRope[stream: ris, breakProc: Break ! IO.EndOfStream => GOTO Exit].token; action[rope]; IF Rope.Length[rope]>1 AND Rope.Fetch[rope, 1] IN ['A..'Z] THEN { WHILE Rope.Length[base: rope]>1 AND Rope.Fetch[base: rope, index: 1] IN ['A..'Z] DO rope _ Rope.Substr[base: rope, start: 1]; ENDLOOP; action[rope]; --With extra leading caps stripped }; EXITS Exit => EXIT }; ENDLOOP; }; CallWhenProfileChanges: ENTRY UserProfile.ProfileChangedProc ~ { ENABLE UNWIND => NULL; <> <> fileName: LIST OF ROPE ~ UserProfile.ListOfTokens[key: "PhoneList.Files", default: NIL]; upEntry: ROPE ~ UserProfile.Line[key: "PhoneList.Files", default: NIL]; IF fileName=NIL THEN MessageWindow.Append[message: "No phone list specified in the User Profile!", clearFirst: TRUE]; IF reason=edit AND Rope.Equal[upEntry, phoneListUPEntry] THEN RETURN; --User edited the profile, but didn't change this entry, so leave alone <> phoneList _ SymTab.Create[mod: 101, case: FALSE]; FOR each: LIST OF ROPE _ fileName, each.rest UNTIL each=NIL DO ENABLE FS.Error => { MessageWindow.Append[message: Rope.Cat["Phonelist problem: ", error.explanation], clearFirst: TRUE]; LOOP; }; stream: IO.STREAM ~ FS.StreamOpen[fileName: each.first]; { DO LineBreak: IO.BreakProc ~ { <> RETURN [IF char='\n THEN sepr ELSE other]; }; line: ROPE ~ IO.GetTokenRope[stream: stream, breakProc: LineBreak ! IO.EndOfStream => GOTO Finished].token; Install: INTERNAL PROC [key: ROPE] ~ { lines: LIST OF ROPE ~ CONS[line, LookupNameInternal[key].line]; [] _ SymTab.Store[x: phoneList, key: key, val: lines]; }; ExtractNames[line, Install]; --Install under each name found ENDLOOP; EXITS Finished => NULL; }; ENDLOOP; [] _ ActivateSpellingCorrection[reinitialize: TRUE]; }; Lookup: Commander.CommandProc ~ { args: CommandTool.ArgumentVector ~ CommandTool.Parse[cmd: cmd]; foundAny: BOOLEAN _ FALSE; FOR arg: CARDINAL IN [1..args.argc) DO found: BOOL; line: LIST OF ROPE; [found, line] _ LookupName[args[arg]]; foundAny _ foundAny OR found; IF found THEN { FOR each: LIST OF ROPE _ line, each.rest UNTIL each=NIL DO IO.PutRope[self: cmd.out, r: Rope.Cat[each.first, "\n"]]; ENDLOOP; } ELSE { corrections: LIST OF ROPE ~ CorrectionToName[args[arg]]; IF corrections=NIL THEN IO.PutRope[self: cmd.out, r: Rope.Cat[args[arg], " not found.\n"]] ELSE { IO.PutRope[self: cmd.out, r: Rope.Cat[args[arg], " not found. Possible corrections:\n"]]; FOR each: LIST OF ROPE _ corrections, each.rest UNTIL each=NIL DO [found, line] _ LookupName[each.first]; foundAny _ foundAny OR found; IF found THEN { FOR each: LIST OF ROPE _ line, each.rest UNTIL each=NIL DO IO.PutRope[self: cmd.out, r: Rope.Cat[each.first, "\n"]]; ENDLOOP; } ENDLOOP; IO.PutRope[self: cmd.out, r: "\n"]; }; }; ENDLOOP; IF ~foundAny THEN RETURN [result: $Failure]; }; LookupNameInternal: INTERNAL PROC [name: ROPE] RETURNS [found: BOOL, line: LIST OF ROPE] ~ { ref: REF; [found, ref] _ SymTab.Fetch[x: phoneList, key: name]; line _ NARROW[ref, LIST OF ROPE]; }; LookupName: PUBLIC ENTRY PROC [name: ROPE] RETURNS [found: BOOL, line: LIST OF ROPE] ~ { ENABLE UNWIND => NULL; [found, line] _ LookupNameInternal[name]; }; spellingActivated: BOOL _ FALSE; bitTable: BitTableLookup.Table; buffer: REF TEXT ~ NEW[TEXT[20]]; ActivateSpellingCorrection: INTERNAL PROC [reinitialize: BOOL _ FALSE] RETURNS [failed: BOOL _ TRUE] ~ { RETURN [~PrincOpsUtils.IsBound[LOOPHOLE[SpellingCorrection.BruteForceCorrection]]]; }; <> <