summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraarne <aarne@chalmers.se>2010-04-06 08:53:44 +0000
committeraarne <aarne@chalmers.se>2010-04-06 08:53:44 +0000
commitba13052d3117c3931a5477a0bbf2d3c38ed749c6 (patch)
treec6049008c3f7e9440a24129db318b517546868c8
parent2ced613d81b1fb93e3e60c974eee73a8872d7093 (diff)
dependency graph can be restricted to some modules; added help dg
-rw-r--r--src/compiler/GF/Command/Commands.hs25
-rw-r--r--src/compiler/GF/Infra/Dependencies.hs41
-rw-r--r--src/compiler/GFI.hs6
3 files changed, 57 insertions, 15 deletions
diff --git a/src/compiler/GF/Command/Commands.hs b/src/compiler/GF/Command/Commands.hs
index 51f1c1426..0ca54839c 100644
--- a/src/compiler/GF/Command/Commands.hs
+++ b/src/compiler/GF/Command/Commands.hs
@@ -208,6 +208,31 @@ allCommands cod env@(pgf, mos) = Map.fromList [
],
needsTypeCheck = False
}),
+ ("dg", emptyCommandInfo {
+ longname = "dependency_graph",
+ syntax = "dg (-only=MODULES)?",
+ synopsis = "print module dependency graph",
+ explanation = unlines [
+ "Prints the dependency graph of source modules.",
+ "Requires that import has been done with the -retain flag.",
+ "The graph is written in the file _gfdepgraph.dot",
+ "which can be further processed by Graphviz (the system command 'dot').",
+ "By default, all modules are shown, but the -only flag restricts them",
+ "by a comma-separated list of patterns, where 'name*' matches modules",
+ "whose name has prefix 'name', and other patterns match modules with",
+ "exactly the same name. The graphical conventions are:",
+ " solid box = abstract, solid ellipse = concrete, dashed ellipse = other",
+ " solid arrow empty head = of, solid arrow = **, dashed arrow = open",
+ " dotted arrow = other dependency"
+ ],
+ flags = [
+ ("only","list of modules included (default: all), literally or by prefix*")
+ ],
+ examples = [
+ "dg -only=SyntaxEng,Food* -- shows only SyntaxEng, and those with prefix Food"
+ ],
+ needsTypeCheck = False
+ }),
("dt", emptyCommandInfo {
longname = "define_tree",
syntax = "dt IDENT (TREE | STRING | \"<\" COMMANDLINE)",
diff --git a/src/compiler/GF/Infra/Dependencies.hs b/src/compiler/GF/Infra/Dependencies.hs
index 9a870b139..82606a865 100644
--- a/src/compiler/GF/Infra/Dependencies.hs
+++ b/src/compiler/GF/Infra/Dependencies.hs
@@ -6,8 +6,11 @@ import GF.Grammar.Grammar
import GF.Infra.Modules
import GF.Infra.Ident
-depGraph :: SourceGrammar -> String
-depGraph = prDepGraph . grammar2moddeps
+import Data.List (nub,isPrefixOf)
+
+-- the list gives the only modules to show, e.g. to hide the library details
+depGraph :: Maybe [String] -> SourceGrammar -> String
+depGraph only = prDepGraph . grammar2moddeps only
prDepGraph :: [(Ident,ModDeps)] -> String
prDepGraph deps = unlines $ [
@@ -47,15 +50,25 @@ data ModDeps = ModDeps {
noModDeps = ModDeps MTAbstract [] [] [] [] [] [] []
-grammar2moddeps :: SourceGrammar -> [(Ident,ModDeps)]
-grammar2moddeps gr = [(i,depMod m) | (i,m) <- modules gr] where
- depMod m = noModDeps{
- modtype = mtype m,
- ofs = case mtype m of
- MTConcrete i -> [i]
- MTInstance i -> [i]
- _ -> [],
- extendeds = map fst (extend m),
- openeds = map openedModule (opens m),
- extrads = mexdeps m
- }
+grammar2moddeps :: Maybe [String] -> SourceGrammar -> [(Ident,ModDeps)]
+grammar2moddeps monly gr = [(i,depMod i m) | (i,m) <- modules gr, yes i]
+ where
+ depMod i m =
+ noModDeps{
+ modtype = mtype m,
+ ofs = case mtype m of
+ MTConcrete i -> [i | yes i]
+ MTInstance i -> [i | yes i]
+ _ -> [],
+ extendeds = nub $ filter yes $ map fst (extend m),
+ openeds = nub $ filter yes $ map openedModule (opens m),
+ extrads = nub $ filter yes $ mexdeps m
+ }
+ yes i = case monly of
+ Just only -> match (showIdent i) only
+ _ -> True
+ match s os = any (\x -> doMatch x s) os
+ doMatch x s = case last x of
+ '*' -> isPrefixOf (init x) s
+ _ -> x == s
+
diff --git a/src/compiler/GFI.hs b/src/compiler/GFI.hs
index e80403145..9561c407f 100644
--- a/src/compiler/GFI.hs
+++ b/src/compiler/GFI.hs
@@ -7,6 +7,7 @@ import GF.Command.Commands
import GF.Command.Abstract
import GF.Command.Parse
import GF.Data.ErrM
+import GF.Data.Operations (chunks)
import GF.Grammar hiding (Ident)
import GF.Grammar.Parser (runP, pExp)
import GF.Grammar.ShowTerm
@@ -133,7 +134,10 @@ loop opts gfenv0 = do
Bad s -> putStrLn $ enc s
loopNewCPU gfenv
"dg":ws -> do
- writeFile "_gfdepgraph.dot" (depGraph sgr)
+ let stop = case ws of
+ ('-':'o':'n':'l':'y':'=':fs):_ -> Just $ chunks ',' fs
+ _ -> Nothing
+ writeFile "_gfdepgraph.dot" (depGraph stop sgr)
putStrLn "wrote graph in file _gfdepgraph.dot"
loopNewCPU gfenv
"eh":w:_ -> do