DIRECTORY Atom USING [GetPName], Commander USING [CommandProc, Register], IO USING [atom, rope, STREAM, EndOfStream, GetRope, GetTokenRope, PutChar, PutF, PutFR, PutRope, RIS], LoganQuery USING [AttributePatterns, PatternsToEntry, ReadAttributePatterns, SyntaxError], Rope USING [ROPE, Cat, Concat, Find, Substr], TapFilter USING [Annotation, AddFilter, DeleteFilter, FilterInfo, LookupFilter, LookupAllFilters, Query, Error], UserProfile USING [Token]; TapCommandsImpl: CEDAR PROGRAM IMPORTS Atom, Commander, IO, LoganQuery, Rope, TapFilter, UserProfile ~ BEGIN ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; usageAddFilter: ROPE = "usage: TapAddFilter name {field(matcher): pattern}* -> {tag: value}*\n e.g. TapAddFilter msgsFromDoug from: *Terry* -> Level: 99"; AddFilterCmd: Commander.CommandProc = { filterDBName, userName: ROPE _ NIL; filterName, query, noteRope, filterID: ROPE; s: STREAM; loc: INT; ap: LoganQuery.AttributePatterns; note: TapFilter.Annotation; loc _ Rope.Find[s1: cmd.commandLine, s2: "->"]; IF loc < 0 THEN GOTO Usage; s _ IO.RIS[Rope.Substr[base: cmd.commandLine, start: 0, len: loc]]; filterName _ IO.GetTokenRope[stream: s ! IO.EndOfStream => GOTO Usage].token; query _ IO.GetRope[s]; noteRope _ Rope.Substr[base: cmd.commandLine, start: loc+2]; s _ IO.RIS[query]; ap _ LoganQuery.ReadAttributePatterns[s ! LoganQuery.SyntaxError => {msg _ IO.PutFR["Query syntax error: %g\n", IO.rope[explanation]]; GOTO End}]; s _ IO.RIS[noteRope]; ap _ LoganQuery.ReadAttributePatterns[s ! LoganQuery.SyntaxError => {msg _ IO.PutFR["Annotation syntax error: %g\n", IO.rope[explanation]]; GOTO End}]; note _ LoganQuery.PatternsToEntry[ap]; filterDBName _ UserProfile.Token[key: "Tapestry.FilterDB"]; IF filterDBName = NIL THEN { msg _ "No user profile entry for Tapestry.FilterDB\n"; GOTO End; }; userName _ UserProfile.Token[key: "Tapestry.UserName"]; IF userName = NIL THEN { msg _ "No user profile entry for Tapestry.UserName\n"; GOTO End; }; filterID _ TapFilter.AddFilter[filterDB: filterDBName, user: userName, filterName: filterName, query: query, annot: note ! TapFilter.Error => {msg _ IO.PutFR["Can't add filter: %g - %g\n", IO.atom[ec], IO.rope[explanation]]; GOTO End}]; msg _ Rope.Concat["Added filter: ", filterID]; EXITS End => RETURN[$Failure, msg]; Usage => RETURN[$Failure, usageAddFilter]; }; usageDeleteFilter: ROPE = "usage: TapDeleteFilter filterName \n e.g. TapDeleteFilter msgsFromDoug"; DeleteFilterCmd: Commander.CommandProc = { filterDBName, userName: ROPE _ NIL; filterName, filterID: ROPE; s: STREAM; s _ IO.RIS[cmd.commandLine]; filterName _ IO.GetTokenRope[stream: s ! IO.EndOfStream => GOTO Usage].token; filterDBName _ UserProfile.Token[key: "Tapestry.FilterDB"]; IF filterDBName = NIL THEN { msg _ "No user profile entry for Tapestry.FilterDB\n"; GOTO End; }; userName _ UserProfile.Token[key: "Tapestry.UserName"]; IF userName = NIL THEN { msg _ "No user profile entry for Tapestry.UserName\n"; GOTO End; }; filterID _ Rope.Cat[userName, "$", filterName]; [] _ TapFilter.DeleteFilter[filterDB: filterDBName, filterID: filterID ! TapFilter.Error => {msg _ IO.PutFR["Can't delete filter: '%g.' %g - %g\n", IO.rope[filterName], IO.atom[ec], IO.rope[explanation]]; GOTO End}]; msg _ Rope.Concat["Deleted filter: ", filterID]; EXITS End => RETURN[$Failure, msg]; Usage => RETURN[$Failure, usageDeleteFilter]; }; usageListFilter: ROPE = "usage: TapListFilter {FilterName | }\n e.g. TapListFilter msgsFromDoug \n TapListFilter"; ListFilterCmd: Commander.CommandProc = { PrintInfo: PROC [name: ROPE, user: ROPE, query: TapFilter.Query, note: TapFilter.Annotation] ~ { IO.PutF[cmd.out, "Filter name: %g\nUser: %g\nQuery: %g\n", IO.rope[name], IO.rope[user], IO.rope[query]]; IO.PutRope[cmd.out, "Annotation:\n"]; FOR aL: TapFilter.Annotation _ note, aL.rest WHILE aL#NIL DO IF aL.first.type#NIL THEN { IO.PutRope[cmd.out, " "]; IO.PutRope[cmd.out, Atom.GetPName[aL.first.type]]; IO.PutRope[cmd.out, ": "]; IO.PutRope[cmd.out, aL.first.value]; IO.PutChar[cmd.out, '\n]; }; ENDLOOP; IO.PutChar[cmd.out, '\n]; }; filterDBName, userName: ROPE _ NIL; filterName, filterID: ROPE; s: STREAM; note: TapFilter.Annotation; user: ROPE; query: TapFilter.Query; filterName _ NIL; s _ IO.RIS[cmd.commandLine]; filterName _ IO.GetTokenRope[stream: s ! IO.EndOfStream => CONTINUE].token; filterDBName _ UserProfile.Token[key: "Tapestry.FilterDB"]; IF filterDBName = NIL THEN { msg _ "No user profile entry for Tapestry.FilterDB\n"; GOTO End; }; userName _ UserProfile.Token[key: "Tapestry.UserName"]; IF userName = NIL THEN { msg _ "No user profile entry for Tapestry.UserName\n"; GOTO End; }; IF filterName = NIL THEN { stuff: LIST OF TapFilter.FilterInfo; stuff _ TapFilter.LookupAllFilters[filterDB: filterDBName ! TapFilter.Error => {msg _ IO.PutFR["Can't list filter: %g - %g\n", IO.atom[ec], IO.rope[explanation]]; GOTO End}]; IF stuff = NIL THEN { msg _ "No filters\n"; GOTO End; }; FOR info: LIST OF TapFilter.FilterInfo _ stuff, info.rest WHILE info#NIL DO PrintInfo[info.first.filterName, info.first.user, info.first.query, info.first.annot]; ENDLOOP; } ELSE { -- just list the filter named name: ROPE; filterID _ Rope.Cat[userName, "$", filterName]; [name, user, query, note] _ TapFilter.LookupFilter[filterDB: filterDBName, filterID: filterID]; IF name = NIL THEN { msg _ IO.PutFR["No such filter %g\n", IO.rope[filterName]]; GOTO End; }; PrintInfo[name: name, user: user, query: query, note: note]; }; EXITS End => RETURN[$Failure, msg]; }; Commander.Register[key: "TapAddFilter", proc: AddFilterCmd, doc: Rope.Concat["Add a new Tapestry filter.\n", usageAddFilter]]; Commander.Register[key: "TapDeleteFilter", proc: DeleteFilterCmd, doc: Rope.Concat["Delete a Tapestry filter.\n", usageDeleteFilter]]; Commander.Register[key: "TapListFilter", proc: ListFilterCmd, doc: Rope.Concat["List a specific Tapestry filter, or list all filters.\n", usageListFilter]]; END. DTapCommandsImpl.mesa Copyright Σ 1989 by Xerox Corporation. All rights reserved. Doug Terry, July 3, 1990 5:15:05 pm PDT Brian Oki, March 3, 1991 3:28 pm PST Commands for adding filters, etc. Filters [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] Parse command line as: name {field(matcher): pattern}* -> {tag: value}*. Check that query and annotations are syntactically correct. Add new filter. [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] Parse command line as: FilterName Look in User Profile entry. [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] Print information Parse command line as: FilterName If filterName is NIL then user wants to list all filters; otherwise, just list the specific filter List all filters Command registrations Κ ˜code•Mark outsideHeaderšœ™Kšœ<™[s1: ROPE, s2: ROPE, pos1: INT _ 0, case: BOOL _ TRUE]šœ/˜/šœ ˜Kšœ˜ —K–9[base: ROPE, start: INT _ 0, len: INT _ 2147483647]šœœœ9˜CK–-[stream: STREAM, breakProc: IO.BreakProc]šœ œœœ˜MKšœœ ˜Kšœ<˜