The Control Flow graph is an extremely powerful tool within Understand that can give you new insights into your codebase, and the ability to analyze it more accurately than you could with the lexer. The graph can now be customized using both the Perl and Python API's as of the release of Understand 6.1.
Perl API
To get started with Perl (necessary if your build is older than 1086), start by downloading the Perl Flowchart from the Custom Graphs page – save it to the scitools\conf\plugin\users\Graph directory so it doesn’t get overridden by the next upgrade. Then open it in your code editor.
That logical control flow structure is obtained by calling $entity->freetext(“CGraph”). That command returns a series of numbers representing the different nodes of the graph. Each node is delimited by a semicolon and the series of numbers inside of those semicolons describe the node. These numbers can be seen in the regular graph by right clicking on an empty area and enabling debug. Note that some of the nodes are hidden by default so disable the filter option to see them.
The numbers can be interpreted as follows: The first number is the node ID. The second line contains the serialized representation of the node: The Node Kind(see the array @names for a list of all of the kinds, or see the table below), Start Line, Start Column, End Line, End Column. The sixth number, if non-empty, is the End Structure Node. All remaining numbers are the successors (or children) of the node.
Normal graph
Same graph with debug options and unfiltered
List of Node Kinds
0 do-while
1 end-do-while
2 case
3 case-when
4 end-case
5 if
6 elsif
7 else
8 end-if
9 loop
10 while-for
11 while
12 for
13 exit
14 exit-when
15 end-loop
16 select
17 select-or
18 select-else
19 select-then-abort
20 end-select
21 switch
22 switch-case
23 switch-default
24 end-switch
25 question-begin
26 question-colon
27 end-question
28 goto
29 raise
30 return
31 terminate
32 break
33 continue
34 throw
35 passive
36 passive-implicit
37 java-block-begin
38 end-java-block
39 ada-block-begin
40 ada-accept-block-begin
41 exception-when
42 end-ada-block
43 try
44 try-catch
45 end-try
46 fortran-arith-if
47 fortran-select-case
48 fortran-case
49 fortran-case-default
50 fortran-end-select
51 fortran-where
52 fortran-else-where
53 fortran-end-where
54 fortran-do
55 fortran-do-infinite
56 fortran-do-while
57 fortran-end-do
58 fortran-until
59 fortran-loop-expr
60 fortran-assigned-goto
61 fortran-computed-goto
62 fortran-cycle
63 fortran-stop
64 fortran-exit-do
65 fortran-exit-for
66 fortran-exit-if
67 fortran-exit-loop
68 fortran-exit-while
69 fortran-exit-do-if
70 fortran-exit-for-if
71 fortran-exit-if-if
72 fortran-exit-loop-if
73 fortran-exit-while-if
74 end-routine
75 repeat-until
76 end-repeat-until
77 try-finally
78 deferred-break
79 deferred-continue
80 deferred-goto
81 deferred-return
82 deferred-throw
83 with-do
84 end-with-do
85 fortran-else-where-cond
86 while-for-else
87 try-else
88 fortran-io-control
89 next
90 next-when
91 case-fallthru
92 jovial3-goto
93 basic-do
94 basic-do-until
95 basic-do-while
96 basic-end-do-loop
97 basic-end-do-loop-until
98 basic-end-do-loop-while
99 basic-exit-do
100 basic-exit-for
101 basic-exit-select
102 basic-exit-try
103 basic-exit-while
104 basic-continue-do
105 basic-continue-for
106 basic-continue-while
107 fortran-call-alt-return
108 conditional-goto
Python API
If you have Understand 6.1, you can go ahead and access the Control Flow Graph using the built-in Python API methods.
Simply call Understand.ent().control_flow_graph() to generate a CFGraph object for an entity. Note that only certain entities are supported, and if no control information is known then None will be returned.
Once you have your Control Flow Graph object, you can call CFGraph.nodes() to return a list of all nodes in the graph, or CFGraph.start() to return just the starting node of the graph.
From your node, there are many ways to navigate the graph or access information about the node, again using the built-in API functions. Here are a few examples:
cfnode.column_begin() will return the beginning file column of the node, or None if there is no location information for it.
cfnode.kind() will return the kind of the node, which can be any of the node kinds listed above
cfnode.children() will return the children of the given node, provided as a list of CFnode objects
For a complete list of the Control Flow Graph methods available with the API, please refer to the PDF attached.