Verified Commit b9f76a1f authored by Camil Staps's avatar Camil Staps 🚀

Combine profile2html and profile2callgrind in one program

parent d48653a4
*.abc *.abc
*.o *.o
profile2html convertprofile
profile2callgrind
definition module Callgrind
from PGCL import :: Profile
write_profile_to_callgrind :: !Profile !*File -> *File
module profile2callgrind implementation module Callgrind
import StdEnv import StdEnv
import StdMaybe
import Data.Error
import Data.Func
import qualified Data.Set
import System.CommandLine
import System.FilePath
import System.Options
from Text import class Text(concat,join), instance Text String
import PGCL import PGCL
:: Options = write_profile_to_callgrind :: !Profile !*File -> *File
{ input :: !FilePath write_profile_to_callgrind profile f
, output :: !FilePath
, min_cumulative_ticks :: !Int
, min_cumulative_words :: !Int
, exclude :: !'Data.Set'.Set String
}
defaultOptions =
{ input = ""
, output = ""
, min_cumulative_ticks = 0
, min_cumulative_words = 0
, exclude = 'Data.Set'.newSet
}
Start w
# ([prog:args],w) = getCommandLine w
# args = parseOptions option_description args defaultOptions
| isError args
= exit (join "\n" [usage prog,"":fromError args]) w
# args = fromOk args
| size args.input==0
= exit "Specify an input file" w
# args & output = if (size args.output==0)
(addExtension args.input "html")
args.output
# (ok,input,w) = fopen args.input FReadData w
| not ok
= exit "Could not open input file" w
# (profile,input) = read_profile input
# (_,w) = fclose input w
| isError profile
= exit ("Could not parse input: "+++fromError profile) w
# profile = prepare args.min_cumulative_ticks args.min_cumulative_words args.exclude (fromOk profile)
# costs = compute_aggregate_costs profile # costs = compute_aggregate_costs profile
# calls = compute_call_matrix profile # calls = compute_call_matrix profile
# (ok,f,w) = fopen args.output FWriteText w = write_profile costs calls profile f
| not ok
= exit "Could not open output file" w
# f = write_profile costs calls profile f
# (_,w) = fclose f w
= w
where
usage prog = concat
[ "Usage: "
, prog
, " [options] INPUT"
]
option_description =
WithHelp True $ Options
[ Shorthand "-o" "--output" $ Option "--output"
(\op opts -> Ok {opts & output=op})
"OUTPUT"
"The output file"
, Shorthand "-e" "--exclude" $ Option "--exclude"
(\e opts -> Ok {opts & exclude='Data.Set'.insert e opts.exclude})
"MODULE:FUNCTION"
"A function to exclude (may be specified multiple times)"
, Option "--min-ticks"
(\t opts -> case toInt t of
0
| t=="0"
-> Ok {opts & min_cumulative_ticks=0}
-> Error [concat ["--min-ticks: invalid integer '",t,"'"]]
t
-> Ok {opts & min_cumulative_ticks=t})
"N"
"Only include cost centres with at least N ticks (cumulatively)"
, Option "--min-words"
(\t opts -> case toInt t of
0
| t=="0"
-> Ok {opts & min_cumulative_words=0}
-> Error [concat ["--min-words: invalid integer '",t,"'"]]
t
-> Ok {opts & min_cumulative_words=t})
"N"
"Only include cost centres with at least N words (cumulatively)"
, Operand
False
(\ip opts
| size opts.input==0
-> Just (Ok {opts & input=ip})
-> Nothing)
"INPUT"
"The input file"
]
exit err w
# (_,w) = fclose (stderr <<< err <<< '\n') w
= setReturnCode -1 w
:: Call = :: Call =
{ call_count :: !Int { call_count :: !Int
......
definition module HTML
from PGCL import :: Profile
write_profile_to_html :: !Profile !*File !*World -> (!*File, !*World)
open_file_in_browser :: !String !*World -> *World
module profile2html implementation module HTML
import StdEnv import StdEnv
import StdMaybe import StdMaybe
import Data.Error import Data.Error
import Data.Func import Data.Func
import qualified Data.Set
import System.CommandLine
import System.File import System.File
import System.FilePath import System.FilePath
import System.Options
import System.OS import System.OS
import System.Process import System.Process
import System._Pointer import System._Pointer
from Text import class Text(concat,join), instance Text String, <+ from Text import class Text(concat), instance Text String
import qualified Text.HTML import Text.HTML
import PGCL import PGCL
:: Options = write_profile_to_html :: !Profile !*File !*World -> (!*File, !*World)
{ input :: !FilePath write_profile_to_html profile f w
, output :: !FilePath
, min_cumulative_ticks :: !Int
, min_cumulative_words :: !Int
, exclude :: !'Data.Set'.Set String
}
defaultOptions =
{ input = ""
, output = ""
, min_cumulative_ticks = 0
, min_cumulative_words = 0
, exclude = 'Data.Set'.newSet
}
Start w
# ([prog:args],w) = getCommandLine w
# args = parseOptions option_description args defaultOptions
| isError args
= exit (join "\n" [usage prog,"":fromError args]) w
# args = fromOk args
| size args.input==0
= exit "Specify an input file" w
# args & output = if (size args.output==0)
(addExtension args.input "html")
args.output
# (ok,input,w) = fopen args.input FReadData w
| not ok
= exit "Could not open input file" w
# (profile,input) = read_profile input
# (_,w) = fclose input w
| isError profile
= exit ("Could not parse input: "+++fromError profile) w
# profile = prepare args.min_cumulative_ticks args.min_cumulative_words args.exclude (fromOk profile)
# (css,w) = readFile (exec_directory </> "profile.css") w # (css,w) = readFile (exec_directory </> "profile.css") w
| isError css | isError css
= exit ("Could not open supporting CSS: "+++toString (fromError css)) w = abort ("Could not open supporting CSS: "+++toString (fromError css)+++"\n")
# css = fromOk css
# (js,w) = readFile (exec_directory </> "profile.js") w # (js,w) = readFile (exec_directory </> "profile.js") w
| isError js | isError js
= exit ("Could not open supporting JavaScript: "+++toString (fromError js)) w = abort ("Could not open supporting JavaScript: "+++toString (fromError js)+++"\n")
# js = fromOk js # f = write_profile (fromOk css) (fromOk js) profile f
# (ok,f,w) = fopen args.output FWriteText w = (f,w)
| not ok
= exit "Could not open output file" w
# f = write_profile css js profile f
# (_,w) = fclose f w
# w = open_file_in_browser args.output w
= w
where
usage prog = concat
[ "Usage: "
, prog
, " [options] INPUT"
]
option_description =
WithHelp True $ Options
[ Shorthand "-o" "--output" $ Option "--output"
(\op opts -> Ok {opts & output=op})
"OUTPUT"
"The output file"
, Shorthand "-e" "--exclude" $ Option "--exclude"
(\e opts -> Ok {opts & exclude='Data.Set'.insert e opts.exclude})
"MODULE:FUNCTION"
"A function to exclude (may be specified multiple times)"
, Option "--min-ticks"
(\t opts -> case toInt t of
0
| t=="0"
-> Ok {opts & min_cumulative_ticks=0}
-> Error [concat ["--min-ticks: invalid integer '",t,"'"]]
t
-> Ok {opts & min_cumulative_ticks=t})
"N"
"Only include cost centres with at least N ticks (cumulatively)"
, Option "--min-words"
(\t opts -> case toInt t of
0
| t=="0"
-> Ok {opts & min_cumulative_words=0}
-> Error [concat ["--min-words: invalid integer '",t,"'"]]
t
-> Ok {opts & min_cumulative_words=t})
"N"
"Only include cost centres with at least N words (cumulatively)"
, Operand
False
(\ip opts
| size opts.input==0
-> Just (Ok {opts & input=ip})
-> Nothing)
"INPUT"
"The input file"
]
exit err w
# (_,w) = fclose (stderr <<< err <<< '\n') w
= setReturnCode -1 w
write_profile :: !String !String !Profile !*File -> *File write_profile :: !String !String !Profile !*File -> *File
write_profile css js p f write_profile css js p f
...@@ -149,8 +58,8 @@ where ...@@ -149,8 +58,8 @@ where
# f = f <<< "<div class=\"entry\">" # f = f <<< "<div class=\"entry\">"
<<< "<div class=\"entry-header\">" <<< "<div class=\"entry-header\">"
<<< if (isEmpty s.children) "" "<span class=\"toggler open\">&#x229f;</span>" <<< if (isEmpty s.children) "" "<span class=\"toggler open\">&#x229f;</span>"
<<< "<span class=\"entry-content\">" <<< 'Text.HTML'.escapeForTextNode p.modules.[cost_centre.cc_module] <<< "<span class=\"entry-content\">" <<< escapeForTextNode p.modules.[cost_centre.cc_module]
<<< ": <span class=\"function\">" <<< 'Text.HTML'.escapeForTextNode cost_centre.cc_name <<< "</span></span>" <<< ": <span class=\"function\">" <<< escapeForTextNode cost_centre.cc_name <<< "</span></span>"
<<< "&nbsp;" <<< "&nbsp;"
<<< "<span class=\"progress words\" title=\"" <<< words <<< "\">" <<< "<span class=\"progress words\" title=\"" <<< words <<< "\">"
<<< if (parent_words==0) "" (concat ["<span class=\"bar\" style=\"",words_width,"\"></span>"]) <<< if (parent_words==0) "" (concat ["<span class=\"bar\" style=\"",words_width,"\"></span>"])
......
module convertprofile
import StdEnv
import StdMaybe
import Data.Error
import Data.Func
import qualified Data.Set
import System.CommandLine
import System.FilePath
import System.Options
from Text import class Text(concat,join), instance Text String
import Callgrind
import HTML
import PGCL
:: Options =
{ input :: !FilePath
, output :: !FilePath
, min_cumulative_ticks :: !Int
, min_cumulative_words :: !Int
, exclude :: !'Data.Set'.Set String
}
defaultOptions =
{ input = ""
, output = "callgrind.out"
, min_cumulative_ticks = 0
, min_cumulative_words = 0
, exclude = 'Data.Set'.newSet
}
Start w
# ([prog:args],w) = getCommandLine w
# args = parseOptions option_description args defaultOptions
| isError args
= exit (join "\n" [usage prog,"":fromError args]) w
# args = fromOk args
| size args.input==0
= exit "Specify an input file" w
# args & output = if (size args.output==0)
(addExtension args.input "html")
args.output
# (ok,input,w) = fopen args.input FReadData w
| not ok
= exit "Could not open input file" w
# (profile,input) = read_profile input
# (_,w) = fclose input w
| isError profile
= exit ("Could not parse input: "+++fromError profile) w
# profile = prepare args.min_cumulative_ticks args.min_cumulative_words args.exclude (fromOk profile)
# (ok,f,w) = fopen args.output FWriteText w
| not ok
= exit "Could not open output file" w
| args.output % (size args.output-5,size args.output-1) == ".html"
# (f,w) = write_profile_to_html profile f w
# (_,w) = fclose f w
# w = open_file_in_browser args.output w
= w
| otherwise
# f = write_profile_to_callgrind profile f
# (_,w) = fclose f w
= w
where
usage prog = concat
[ "Usage: "
, prog
, " [options] INPUT"
]
option_description =
WithHelp True $ Options
[ Shorthand "-o" "--output" $ Option "--output"
(\op opts -> Ok {opts & output=op})
"OUTPUT"
"The output file (either *.html or callgrind.out[.*])"
, Shorthand "-e" "--exclude" $ Option "--exclude"
(\e opts -> Ok {opts & exclude='Data.Set'.insert e opts.exclude})
"MODULE:FUNCTION"
"A function to exclude (may be specified multiple times)"
, Option "--min-ticks"
(\t opts -> case toInt t of
0
| t=="0"
-> Ok {opts & min_cumulative_ticks=0}
-> Error [concat ["--min-ticks: invalid integer '",t,"'"]]
t
-> Ok {opts & min_cumulative_ticks=t})
"N"
"Only include cost centres with at least N ticks (cumulatively)"
, Option "--min-words"
(\t opts -> case toInt t of
0
| t=="0"
-> Ok {opts & min_cumulative_words=0}
-> Error [concat ["--min-words: invalid integer '",t,"'"]]
t
-> Ok {opts & min_cumulative_words=t})
"N"
"Only include cost centres with at least N words (cumulatively)"
, Operand
False
(\ip opts
| size opts.input==0
-> Just (Ok {opts & input=ip})
-> Nothing)
"INPUT"
"The input file"
]
exit err w
# (_,w) = fclose (stderr <<< err <<< '\n') w
= setReturnCode -1 w
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