Commit | Line | Data |
---|---|---|
2b05907b SK |
1 | #! /bin/bash |
2 | ||
f038cbff SK |
3 | declare -A opts=( |
4 | ['--fun']='' | |
5 | ['--out']='report' # report | edges | graph | |
6 | ) | |
7 | ||
8 | while : | |
9 | do | |
10 | case "$1" in | |
11 | --) | |
12 | shift | |
13 | break | |
14 | ;; | |
15 | --*) | |
16 | key="$1" | |
17 | val="$2" | |
18 | if [ -v opts["$key"] ] | |
19 | then | |
20 | if [ "$val" != "" ] | |
21 | then | |
22 | opts["$key"]="$val" | |
23 | shift | |
24 | shift | |
25 | else | |
26 | echo "Option $key requires an argument" >&2 | |
27 | exit 1 | |
28 | fi | |
29 | else | |
30 | echo "Unknown option: $key" >&2 | |
31 | exit 1 | |
32 | fi | |
33 | ;; | |
34 | *) | |
35 | break | |
36 | esac | |
37 | done | |
38 | ||
2b05907b | 39 | target_module="$1" |
f038cbff SK |
40 | shift |
41 | target_fun_regex="${opts['--fun']}" | |
42 | output_type="${opts['--out']}" | |
2b05907b SK |
43 | dirs=$@ |
44 | ||
f038cbff SK |
45 | printf '[DEBUG] target_module : "%s"\n' "$target_module" >&2 |
46 | printf '[DEBUG] target_fun_regex : "%s"\n' "$target_fun_regex" >&2 | |
47 | printf '[DEBUG] dirs : "%s"\n' "$dirs" >&2 | |
48 | printf '[DEBUG] output_type : "%s"\n' "$output_type" >&2 | |
49 | ||
2b05907b SK |
50 | find $dirs -type f -name '*.erl' -exec grep -Hn "\<$target_module\>:" '{}' \; \ |
51 | | sed 's/%.*$//g' \ | |
15f22284 SK |
52 | | awk \ |
53 | -F "${target_module}:" \ | |
54 | -v target_module="$target_module" \ | |
f038cbff | 55 | -v output_type="$output_type" \ |
15f22284 | 56 | -v target_fun_regex="$target_fun_regex" ' |
2b05907b SK |
57 | $1 && $2 { |
58 | caller_module_file = $1 | |
59 | sub(":.*$", "", caller_module_file) | |
60 | ||
61 | called_function = $2 | |
62 | sub("\\(.*$", "", called_function) | |
63 | ||
64 | if (called_function ~ /^[a-z][a-zA-Z_0-9]+$/) { | |
fc84ff9c | 65 | if (called_function ~ target_fun_regex) { |
4cc39e2a | 66 | Calls[called_function]++ |
fc84ff9c SK |
67 | Calls_from[caller_module_file, called_function]++ |
68 | Caller_modules[caller_module_file]++ | |
69 | } | |
2b05907b SK |
70 | } else { |
71 | printf \ | |
72 | "[WARN] skipped an invalid erlang function name. File: \"%s\", function: \"%s\", original line: \"%s\"\n", \ | |
73 | caller_module_file, called_function, $0 \ | |
74 | > "/dev/stderr" | |
75 | } | |
76 | } | |
77 | ||
78 | END { | |
f038cbff SK |
79 | if (output_type == "report") { |
80 | report() | |
81 | } else if (output_type == "edges") { | |
82 | edges() | |
83 | } else if (output_type == "graph") { | |
84 | printf "digraph {\n" | |
85 | vertices() # Vertices must be printed before edges, else records arent recognized. | |
86 | edges() | |
87 | printf "}\n" | |
88 | } else { | |
89 | printf "[ERROR] Unknown output type: \"%s\"\n", output_type > "/dev/stderr" | |
90 | } | |
91 | } | |
4cc39e2a | 92 | |
f038cbff SK |
93 | function vertices() { |
94 | printf "node [shape=record];\n" | |
95 | printf "%s [label=\"", target_module; | |
96 | sep = "" | |
97 | for (called_fun in Calls) { | |
98 | printf "%s<%s> %s", sep, called_fun, called_fun | |
99 | sep = " | " | |
100 | } | |
101 | printf "\"];\n" | |
102 | } | |
103 | ||
104 | function edges() { | |
105 | for (cf in Calls_from) { | |
106 | split(cf, call, SUBSEP) | |
107 | caller_mod = call[1] | |
108 | called_mod = target_module | |
109 | called_fun = call[2] | |
110 | printf("\"%s\" -> %s:%s\n", caller_mod, called_mod, called_fun) | |
111 | } | |
112 | } | |
113 | ||
114 | function report() { | |
115 | indent = " " | |
4cc39e2a | 116 | print "group-by-caller" |
2b05907b | 117 | for (caller_module_file in Caller_modules) { |
4cc39e2a | 118 | printf "%s%s\n", indent, caller_module_file; |
6a53be4c | 119 | sort = "sort -n -k 2 -r | column -t | sed \"s/^/" indent indent "/\"" |
2b05907b SK |
120 | for (cf in Calls_from) { |
121 | split(cf, call, SUBSEP); | |
fc84ff9c | 122 | if (call[1] == caller_module_file) |
6a53be4c | 123 | printf "%s %d\n", call[2], Calls_from[cf] | sort; |
2b05907b | 124 | } |
6a53be4c | 125 | close(sort) |
2b05907b SK |
126 | } |
127 | ||
4cc39e2a | 128 | print "all" |
6a53be4c | 129 | sort = "sort -n -k 2 -r | column -t | sed \"s/^/" indent "/\"" |
2b05907b | 130 | for (called_function in Calls) |
6a53be4c SK |
131 | printf "%s %d\n", called_function, Calls[called_function] | sort |
132 | close(sort) | |
2b05907b | 133 | }' |