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 = { 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]]]; }; CorrectionToName: PUBLIC ENTRY PROC [name: ROPE] RETURNS [possibilities: LIST OF ROPE _ NIL] ~ { ENABLE UNWIND => NULL; SeeIfInWordTable: PROC [r: REF TEXT] RETURNS [BOOL] ~ { Process.CheckForAbort[]; RETURN [SymTab.Fetch[x: phoneList, key: Rope.FromRefText[s: r]].found]; }; SeeIfInBitTable: PROC [r: REF TEXT] RETURNS [BOOL] ~ { RETURN [BitTableLookup.Lookup[bitTable, r]]; }; IF ActivateSpellingCorrection[] THEN RETURN[NIL]; possibilities _ SpellingCorrection.BruteForceCorrection[name, SeeIfInWordTable, buffer].corrections; }; UserProfile.CallWhenProfileChanges[proc: CallWhenProfileChanges]; Commander.Register[key: "PhoneNumberOf", proc: Lookup, doc: "Look up phone numbers from maintained list (PhoneNumberOf lastName lastName ...)"]; END. ŒPhoneListImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Eric Nickell, October 30, 1985 11:44:43 am PST Last Edited by: Gasbarro October 14, 1985 7:28:09 pm PDT This is the monitored data [char: CHAR] RETURNS [IO.CharClass] ProfileChangedProc: TYPE = PROC [reason: ProfileChangeReason]; ProfileChangeReason: TYPE = {firstTime, rollBack, edit}; Here, we know that the user changed the PhoneList.Files entry. BreakProc: TYPE = PROC [char: CHAR] RETURNS [CharClass]; ActivateSpellingCorrection: INTERNAL PROC [reinitialize: BOOL _ FALSE] RETURNS [failed: BOOL _ TRUE] ~ { SELECT TRUE FROM spellingActivated AND ~reinitialize => RETURN [FALSE]; PrincOpsUtils.IsBound[LOOPHOLE[SpellingCorrection.BruteForceCorrection]] AND PrincOpsUtils.IsBound[LOOPHOLE[BitTableLookup.Lookup]] => { InsertNameInTable: SymTab.EachPairAction = { [key: SymTab.Key, val: SymTab.Val] RETURNS [quit: BOOL] BitTableLookup.Insert[bitTable, Rope.ToRefText[base: key]]; RETURN [FALSE]; }; bitTable _ BitTableLookup.Create[20000]; [] _ SymTab.Pairs[x: phoneList, action: InsertNameInTable]; spellingActivated _ TRUE; RETURN [FALSE]; }; ENDCASE => RETURN [TRUE]; }; Κ ‘˜™Icodešœ Οmœ1™Kš‘œžœ™8Kš œ žœžœžœ=žœ˜XK–$[key: ROPE, default: ROPE _ NIL]šœ žœ5žœ˜GK–-[message: ROPE, clearFirst: BOOL _ FALSE]šžœ žœžœ[žœ˜uK˜K–8[mod: SymTab.SeqIndex _ 21B (17), case: BOOL _ TRUE]š žœ žœ'žœžœ G˜K˜K™>Kšœ*žœ˜1K˜š žœžœžœžœžœžœž˜>šžœžœ ˜K–Z[r1: ROPE _ NIL, r2: ROPE _ NIL, r3: ROPE _ NIL, r4: ROPE _ NIL, r5: ROPE _ NIL]šœ_žœ˜eKšžœ˜Kšœ˜—K–‘[fileName: ROPE, accessOptions: FS.AccessOptions _ read, streamOptions: FS.StreamOptions _ (5)[TRUE, TRUE, TRUE, TRUE, TRUE], keep: CARDINAL _ 1B (1), createByteCount: FS.ByteCount _ 2560, streamBufferParms: FS.StreamBufferParms _ [vmPagesPerBuffer: 8, nBuffers: 2], extendFileProc: FS.ExtendFileProc, wantedCreatedTime: GMT _ --{UnknownError[sig: 75022B, msg: 177777B]}--, remoteCheck: BOOL _ TRUE, wDir: ROPE _ NIL]šœžœžœžœ"˜8–[stream: STREAM]˜šž˜–-[stream: STREAM, breakProc: IO.BreakProc]š’ œžœ˜Kš ‘ œžœžœžœžœ ™8Kšžœžœ žœžœ˜*K˜—Kš œžœžœ5žœžœ˜kš‘œžœžœžœ˜&Kš œžœžœžœžœ%˜?Kšœ6˜6K˜—K–7[x: SymTab.Ref, key: SymTab.Key, val: SymTab.Val]šœ ˜