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.