<> <> <> << >> DIRECTORY Atom USING [GetPropFromList], Commander USING [CommandProc, Register], CommandTool USING [ArgumentVector, Parse], FileNames USING [ResolveRelativePath], IO USING [int, PutF, rope, STREAM, Flush], FS USING [StreamOpen, OpenFileFromStream, Close, EnumerateForNames, NameProc, ExpandName, ComponentPositions, Error], TiogaAccess USING [FromFile, GetExternalProp, GetNodeProps, Reader, DoneWith], SymTab USING [Create, EachPairAction, Fetch, Pairs, Ref, Store, Val], Rope USING [ROPE, Substr, Equal, Find]; StyleList: CEDAR PROGRAM IMPORTS Commander, CommandTool, FileNames, FS, IO, TiogaAccess, Atom, SymTab, Rope = BEGIN StyleListProc: Commander.CommandProc ~ { <> argv: CommandTool.ArgumentVector; reader: TiogaAccess.Reader; styleTable: SymTab.Ref; styleName: Rope.ROPE; Entry: TYPE ~ REF EntryRep; EntryRep: TYPE ~ RECORD[ entry: INT ]; nTimes: Entry; argNum: INT _ 0; val: SymTab.Val; styleLogStream: IO.STREAM _ FS.StreamOpen["StyleList.log", $create]; fileLogStream: IO.STREAM _ FS.StreamOpen["MesaStyleFiles.log", $create]; styleProperty: ATOM _ $Prefix; pattern: Rope.ROPE; currentDirectory: Rope.ROPE; PrintStyleStats: PROC ~ { IO.PutF[styleLogStream, "Style Counts for %g\n\n", IO.rope[pattern]]; [] _ SymTab.Pairs[styleTable, PrintTableEntry]; }; PrintTableEntry: SymTab.EachPairAction = { <<[key: SymTab.Key, val: SymTab.Val] RETURNS [quit: BOOL]>> e: Entry _ NARROW[val]; IO.PutF[styleLogStream, " %g:\t%g\n", IO.rope[key], IO.int[e.entry]]; RETURN [FALSE]; }; ProcessFile: FS.NameProc = { <<[fullFName: ROPE] RETURNS [continue: BOOL]>> positions: FS.ComponentPositions; noDir: BOOL; fullFName _ FileNames.ResolveRelativePath[fullFName]; [fullFName, positions, noDir] _ FS.ExpandName[fullFName]; IF Rope.Equal[Rope.Substr[fullFName, positions.ext.start, positions.ext.length], "bcd", FALSE] OR Rope.Equal[Rope.Substr[fullFName, positions.ext.start, positions.ext.length], "press", FALSE] THEN RETURN[TRUE]; reader _ TiogaAccess.FromFile[fullFName ! FS.Error => GO TO Error]; styleName _ TiogaAccess.GetExternalProp[ styleProperty, Atom.GetPropFromList[TiogaAccess.GetNodeProps[reader], styleProperty] ]; IF Rope.Find[s1:styleName, s2:"mesa", case:FALSE] # -1 THEN LogMesaFile[fullFName, positions]; val _ SymTab.Fetch[styleTable, styleName].val; IF (nTimes _ NARROW[val]) # NIL THEN nTimes.entry _ nTimes.entry+1 ELSE { nTimes _ NEW[EntryRep]; nTimes.entry _ 1; }; [] _ SymTab.Store[styleTable, styleName, nTimes]; TiogaAccess.DoneWith[reader]; continue _ TRUE; EXITS Error => continue _ TRUE; }; LogMesaFile: PROC [name: Rope.ROPE, positions: FS.ComponentPositions] ~ { dir: Rope.ROPE _ Rope.Substr[name, positions.server.start-1, positions.base.start-positions.server.start+1]; IF NOT Rope.Equal[currentDirectory, dir] THEN { currentDirectory _ dir; IO.PutF[fileLogStream, "\nDirectory %g:\n", IO.rope[currentDirectory]]; }; IO.PutF[fileLogStream, " %g\n", IO.rope[Rope.Substr[name, positions.base.start, positions.base.length+positions.ext.length+positions.ver.length+2]]]; }; argv _ CommandTool.Parse[cmd -- Exception handler should go here --]; IF argv.argc < 2 THEN GOTO Usage; styleTable _ SymTab.Create[case: FALSE]; pattern _ argv[1]; pattern _ FileNames.ResolveRelativePath[pattern]; pattern _ FS.ExpandName[pattern].fullFName; IO.PutF[fileLogStream, "Mesa style files in %g\n\n", IO.rope[pattern]]; [] _ FS.EnumerateForNames[pattern, ProcessFile]; PrintStyleStats; styleLogStream.Flush; FS.Close[FS.OpenFileFromStream[styleLogStream]]; fileLogStream.Flush; FS.Close[FS.OpenFileFromStream[fileLogStream]]; EXITS Usage => RETURN [$Failure, "Usage: StyleList list-of-patterns\n"]; }; Commander.Register["StyleList", StyleListProc, "Collect style distribution info."]; END.