Commit 763aa1a8 authored by Michael Hanus 's avatar Michael Hanus

Executables checked for existence

parent 53eedad6
......@@ -10,6 +10,7 @@
"base" : ">= 3.0.0, < 4.0.0",
"currypath" : ">= 3.0.0, < 4.0.0",
"directory" : ">= 3.0.0, < 4.0.0",
"execpath" : ">= 3.0.0, < 4.0.0",
"filepath" : ">= 3.0.0, < 4.0.0",
"flatcurry" : ">= 3.0.0, < 4.0.0",
"graphviz" : ">= 3.0.0, < 4.0.0",
......
......@@ -2,7 +2,7 @@
--- An implementation of term graphs used by the ICurry interpreter.
---
--- @author Michael Hanus
--- @version November 2020
--- @version January 2021
------------------------------------------------------------------------------
module ICurry.Graph
......@@ -11,11 +11,10 @@ module ICurry.Graph
import Data.List ( intercalate, nub )
import System.IO ( hPutStr, hClose )
import Data.GraphViz as Dot
import System.IOExts ( connectToCommand )
import System.Process ( system )
import ShowDotGraph as Dot
------------------------------------------------------------------------------
--- Views a dot graph as PDF.
--- If the first argument is `(Just c)`, the command `c`
......
......@@ -2,7 +2,7 @@
--- This module contains a simple compiler from FlatCurry to ICurry programs.
---
--- @author Michael Hanus
--- @version December 2020
--- @version January 2021
------------------------------------------------------------------------------
module ICurry.Main where
......@@ -13,6 +13,7 @@ import System.Environment ( getArgs )
import System.Console.GetOpt
import System.CurryPath ( runModuleAction )
import System.Path ( fileInPath )
import System.Process ( exitWith )
import ICurry.Compiler
......@@ -32,7 +33,7 @@ testI =
banner :: String
banner = unlines [bannerLine, bannerText, bannerLine]
where
bannerText = "ICurry Compiler (Version of 26/12/20)"
bannerText = "ICurry Compiler (Version of 11/01/21)"
bannerLine = take (length bannerText) (repeat '=')
main :: IO ()
......@@ -44,8 +45,22 @@ main = do
[p] -> runModuleAction (icurryOnModule opts) p
_ -> error "Too many module names provided"
checkExecutables :: ICOptions -> IO ()
checkExecutables opts =
if null (optMain opts) || not (optShowGraph opts)
then return ()
else mapM_ checkExec ["dot", optViewPDF opts]
where
checkExec p = do
exp <- fileInPath p
unless exp $ do
putStrLn $ "Executable '" ++ p ++ "' not found in path: " ++
"icurry interpreter terminated"
exitWith 1
icurryOnModule :: ICOptions -> String -> IO ()
icurryOnModule opts modname = do
checkExecutables opts
iprog <- icCompile opts modname
let imain = optMain opts
if null imain
......
--------------------------------------------------------------------------
--- A simple library for graph visualization with
--- [Graphviz](http://www.graphviz.org/).
--- It provides a data structure to represent graphs and operations
--- to visualize them.
---
--- @author Michael Hanus
--- @version November 2020
--------------------------------------------------------------------------
module ShowDotGraph
( DotGraph, dgraph, ugraph, Node(..), Edge(..)
, viewDotGraph, showDotGraph, showDotGraphWithAttrs
, getDotViewCmd, setDotViewCmd )
where
import Data.Char ( isAlphaNum )
import Data.List ( intercalate, last )
import System.IO ( hClose, hPutStr )
import Data.PropertyFile ( getPropertyFromFile, updatePropertyFile )
import System.CurryPath ( curryrcFileName )
import System.IOExts ( connectToCommand )
--------------------------------------------------------------------------
-- Data types for graphs.
--- A Dot graph consists of a name and a list of nodes and edges.
--- It can be either directed (`DGraph`) or undirected (`UGraph`).
data DotGraph = DGraph String [Node] [Edge]
| UGraph String [Node] [Edge]
--- Constructs a directed graph from a name and a list of nodes and edges.
dgraph :: String -> [Node] -> [Edge] -> DotGraph
dgraph name nodes edges = DGraph name nodes edges
--- Constructs an undirected graph from a name and a list of nodes and edges.
ugraph :: String -> [Node] -> [Edge] -> DotGraph
ugraph name nodes edges = UGraph name nodes edges
--- A node of a dot graph consists of a name and a list of attributes
--- for this node.
data Node = Node String [(String,String)]
--- An edge of a dot graph consists of the names of the source and target node
--- and a list of attributes for this edge.
data Edge = Edge String String [(String,String)]
--------------------------------------------------------------------------
--- Visualize a DOT graph with the `dotviewcommand` specified in
--- the rc file of the Curry system.
-- A dependency graph consists of a list of triples of the form (n,as,ms),
-- where n is a node name, as (dot) attributes for node n, and ms the list
-- of direct dependents from n.
viewDotGraph :: DotGraph -> IO ()
viewDotGraph = viewDot . showDotGraph
--- Shows a Dot graph as a string of the DOT language.
showDotGraph :: DotGraph -> String
showDotGraph g = showDotGraphWithAttrs "" g
--- Shows a Dot graph as a string of the DOT language.
--- The second argument contains a string of graph attributes
--- of the DOT languages, e.g., `ordering=out;'.
showDotGraphWithAttrs :: String -> DotGraph -> String
showDotGraphWithAttrs attrs (DGraph name nodes edges) =
"digraph \"" ++ name ++ "\"" ++ graphbody2dot True attrs nodes edges
showDotGraphWithAttrs attrs (UGraph name nodes edges) =
"graph \"" ++ name ++ "\"" ++ graphbody2dot False attrs nodes edges
graphbody2dot :: Bool -> String -> [Node] -> [Edge] -> String
graphbody2dot directed attrs nodes edges =
"{\n" ++ (if null attrs then "" else attrs ++ "\n")
++ concatMap node2dot nodes
++ concatMap (edge2dot directed) edges ++ "}\n"
node2dot :: Node -> String
node2dot (Node nname attrs) =
showDotID nname ++ showDotAttrs attrs ++ ";\n"
edge2dot :: Bool -> Edge -> String
edge2dot directed (Edge i j attrs) =
showDotID i ++ edgeOp ++ showDotID j ++ showDotAttrs attrs ++ ";\n"
where
edgeOp = if directed then " -> " else " -- "
showDotAttrs :: [(String, String)] -> String
showDotAttrs attrs =
if null attrs then ""
else '[' : intercalate "," (map showDotAttr attrs) ++ "]"
--- Shows an attribute of a graph as a string of the DOT language.
--- If the attribute name is `label` and its value is enclosed in
--- angle brackets, it is shown as an HTML-like label, otherwise it is
--- enclosed in quotation marks.
showDotAttr :: (String,String) -> String
showDotAttr (name,value)
| name == "label" && not (null value) && head value == '<' && last value == '>'
= "label=" ++ value
| otherwise
= name ++ "=\"" ++ value ++ "\""
showDotID :: String -> String
showDotID s | all isAlphaNum s = s
| otherwise = '"' : concatMap escapeDQ s ++ "\""
where
escapeDQ c = if c=='"' then "\\\"" else [c]
--- Visualize a string of the DOT langugage with the `dotviewcommand`
--- from the rc file of the Curry system.
viewDot :: String -> IO ()
viewDot dottxt = do
dotview <- getDotViewCmd
dotstr <- connectToCommand dotview
hPutStr dotstr dottxt
hClose dotstr
-------------------------------------------------------------------------
--- Read the command for viewing dot files from the rc file of the
--- Curry system.
getDotViewCmd :: IO String
getDotViewCmd = do
rcfile <- curryrcFileName
getPropertyFromFile rcfile "dotviewcommand" >>= return . maybe "" id
--- Sets the command for viewing dot files in the rc file of the
--- Curry system.
setDotViewCmd :: String -> IO ()
setDotViewCmd dvcmd = do
rcfile <- curryrcFileName
updatePropertyFile rcfile "dotviewcommand" dvcmd
-------------------------------------------------------------------------
{-
Example settings in rc file:
dotviewcommand=dot -Tpdf > /tmp/dotxxx && acroread /tmp/dotxxx
dotviewcommand=neato -Tpdf > /tmp/dotxxx && acroread /tmp/dotxxx
dotviewcommand=circo -Tpdf > /tmp/dotxxx && acroread /tmp/dotxxx
dotviewcommand=fdp -Tpdf > /tmp/dotxxx && acroread /tmp/dotxxx
-}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment