diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | doc/cflow.texi | 381 |
2 files changed, 329 insertions, 60 deletions
@@ -1,3 +1,11 @@ +2005-09-24 Sergey Poznyakoff <gray@gnu.org.ua> + + * doc/cflow.texi: Updated + * doc/d.c: Rewritten to better suite sample purposes. + * src/Makefile.am (chart.cflow): Modified rule + * src/cflow.h (CFLOW_PREPROC): Changed default preprocessor to + /usr/bin/cpp. + 2005-09-21 Sergey Poznyakoff <gray@gnu.org.ua> * src/c.l (types): Add "restrict". diff --git a/doc/cflow.texi b/doc/cflow.texi index f862f4e..dd50c50 100644 --- a/doc/cflow.texi +++ b/doc/cflow.texi @@ -73,8 +73,8 @@ documents GNU cflow Version @value{VERSION}. * Direct and Reverse:: Two Types of Flow Trees. * Output Formats:: Supported Output Formats. * Recursive Calls:: Handling Recursive Calls. -* Preprocessing:: Source Files Can Be Preprocessed Before Analyzing. * Symbols:: Controlling Symbol Input and Output. +* Preprocessing:: Source Files Can Be Preprocessed Before Analyzing. * Cross-References:: Cross-Reference Output. * ASCII Tree:: Using ASCII Art to Produce Flow Trees. * Configuration:: Configuration Files and Variables. @@ -372,7 +372,7 @@ file will look as follows: for existence of each output format. Explain that more formats will appear in the future.} -@node Recursive Calls, Preprocessing, Output Formats, Top +@node Recursive Calls, Symbols, Output Formats, Top @chapter Handling Recursive Calls. @cindex Recursive functions Sometimes programs contain functions that recursively call @@ -384,88 +384,349 @@ recursive calls to this function are marked with a @samp{(recursive: see reference line number where the @dfn{recursion root} definition was displayed. - To illustrate this, let's consider the following implementation -of @dfn{Ackermann's function}: + To illustrate this, let's consider the following program, that prints +recursive listing of a directory, allowing to cut off at the arbitrary +nesting level: @smallexample -@group -@verbatiminclude ack.c -@end group +@verbatiminclude d.c +@end smallexample + + Running @command{cflow} on this program produces the following graph: + +@anchor{sample flowchart} +@smallexample +$ cflow --number d.c + 1 main() <int main (int argc,char **argv) at d.c:85>: + 2 fprintf() + 3 atoi() + 4 printdir() <void printdir (int level,char *name) at d.c:42> (R): + 5 getcwd() + 6 perror() + 7 chdir() + 8 opendir() + 9 readdir() + 10 printf() + 11 ignorent() <int ignorent (char *name) at d.c:28>: + 12 strcmp() + 13 isdir() <int isdir (char *name) at d.c:12>: + 14 stat() + 15 perror() + 16 S_ISDIR() + 17 putchar() + 18 printdir() + <void printdir (int level,char *name) at d.c:42> + (recursive: see 4) + 19 closedir() @end smallexample - Analyzing it with @command{cflow} gives: + The @code{printdir} description in line 4 shows that the function +is recursive. The recursion call is shown in line 19. +@node Symbols, Preprocessing, Recursive Calls, Top +@chapter Controlling Symbol Types + + An alert reader has already noticed something strange in the +above output: the function @code{_exit} is missing, although according +to the source file it is called twice by @code{printdir}. It is +because by default @command{cflow} omits from its output all symbols +beginning with underscore character. To include these symbols as well, +specify @option{-i _} (or @option{--include _}) command line option. +Continuing our example: + @smallexample -@group -$ cflow ack.c -ack() <u_long ack (u_long a,u_long b) at ack.c:4> (R): - ack() <u_long ack (u_long a,u_long b) at ack.c:4> (recursive: see 1) -@end group +$ cflow --number -i _ d.c + 1 main() <int main (int argc,char **argv) at d.c:85>: + 2 fprintf() + 3 atoi() + 4 printdir() <void printdir (int level,char *name) at d.c:42> (R): + 5 getcwd() + 6 perror() + 7 _exit() + 8 chdir() + 9 opendir() + 10 readdir() + 11 printf() + 12 ignorent() <int ignorent (char *name) at d.c:28>: + 13 strcmp() + 14 isdir() <int isdir (char *name) at d.c:12>: + 15 stat() + 16 perror() + 17 S_ISDIR() + 18 putchar() + 19 printdir() + <void printdir (int level,char *name) at d.c:42> + (recursive: see 4) + 20 closedir() @end smallexample - To provide a more detailed example, consider the following -program, that prints recursive listing of a directory: +@cindex @option{-i} introduced +@cindex @option{--include} introduced +@cindex Symbol classes defined +@anchor{--include} + In general, @option{--include} takes an argument specifying a +list of @dfn{symbol classes}. Default option behavior is to include +the requested classes to the output. If the argument begins with a +minus or caret sign, this behavior is reversed and the requested +symbol classes are excluded from the output. + +@cindex Including symbols that begin with an underscore +@cindex Excluding symbol classes + The symbol class @samp{_} includes symbols whose name begin with an +underscore. Another useful symbol class is @samp{s}, representing +@dfn{static functions or data}. By default, static functions are +always included in the output. To omit them, one can give +@option{-i ^s} (or @option{-i -s}@footnote{Notice that @option{-i -s} +is a single option, here @code{-s} is not an option, in spite of its +leading dash character. Since this might be confusing, we prefer +using @samp{^} instead of @samp{-} to denote symbol exclusion.}) +command line option. Our sample program @file{d.c} defines static +function @code{isdir}, running @command{cflow -i ^s}, completely omits +this function and its callees from the resulting graph: @smallexample -@verbatiminclude d.c +$ cflow --number -i ^s d.c + 1 main() <int main (int argc,char **argv) at d.c:85>: + 2 fprintf() + 3 atoi() + 4 printdir() <void printdir (int level,char *name) at d.c:42> (R): + 5 getcwd() + 6 perror() + 7 chdir() + 8 opendir() + 9 readdir() + 10 printf() + 11 ignorent() <int ignorent (char *name) at d.c:28>: + 12 strcmp() + 13 putchar() + 14 printdir() + <void printdir (int level,char *name) at d.c:42> + (recursive: see 4) + 15 closedir() @end smallexample - A brief listing for this program follows (long lines are split -for readability): + Actually, the exclusion sign (@samp{^} or @samp{-}) can be used +in any place in @option{-i} argument, not only at the beginning. Thus, +option @option{-i _^s} means ``@i{include symbols, beginning with +underscore and exclude static functions}''. Several @option{-i} options +accumulate, so the previous example can also be written as +@option{-i _ -i ^s}. + + It is important to notice that by default @command{cflow} graphs +contain only functions. The symbol class @samp{x} contains @dfn{data +symbols}, both global and static, so to include these in the output, +use option @option{-i x}. For example: +@anchor{x flowchart} @smallexample -$ cflow --number --brief d.c - 1 main() <int main (int argc,char **argv) at d.c:83>: +$ cflow --number -i x d.c + 1 main() <int main (int argc,char **argv) at d.c:85>: 2 fprintf() - 3 printdir() <void printdir (int level,char *prefix,char - *name) at d.c:52> (R): - 4 mkfullname() <char *mkfullname (char *prefix, - char *name) at d.c:13>: - 5 malloc() - 6 strlen() - 7 strcat() - 8 strcpy() - 9 strdup() - 10 opendir() - 11 perror() - 12 exit() + 3 stderr + 4 max_level <int max_level at d.c:37> + 5 atoi() + 6 printdir() <void printdir (int level,char *name) at d.c:42> (R): + 7 DIR + 8 dir + 9 getcwd() + 10 perror() + 11 chdir() + 12 opendir() 13 readdir() 14 printf() - 15 ignorent() <int ignorent (char *name) at d.c:43>: - 16 strcmp() - 17 isdir() <int isdir (char *prefix,char *name) at d.c:26>: - 18 stat() - 19 mkfullname() <char *mkfullname (char *prefix, - char *name) at d.c:13>: [see 4] + 15 ignorent() <int ignorent (char *name) at d.c:28>: + 16 ignored_names <char *ignored_names[] at d.c:24> + 17 strcmp() + 18 isdir() <int isdir (char *name) at d.c:12>: + 19 stat() 20 perror() - 21 free() - 22 S_ISDIR() - 23 printdir() <void printdir (int level,char *prefix, - char *name) at d.c:52> (recursive: see 3) [see 3] - 24 free() - 25 closedir() + 21 S_ISDIR() + 22 NULL + 23 max_level <int max_level at d.c:37> + 24 putchar() + 25 printdir() + <void printdir (int level,char *name) at d.c:42> + (recursive: see 6) + 26 closedir() @end smallexample - The @code{printdir} description in line 3 shows that the function -is recursive. The recursion call is shown in line 23. It contains -references to the recursion root, and to the function definition (in -this particular example they refer to the same line). - -@node Preprocessing, Symbols, Recursive Calls, Top + Lines 3 and 4 show data symbols, the latter is listed with its +definition and location, since it is declared in the input +file. A rather confusing result appears in lines 7 and 8. Why both type name +@code{DIR} and automatic variable @code{dir} are listed as data? + + To answer this question, let's first describe the @command{cflow} +notion of symbols. The utility keeps its @dfn{symbol tables}, which +are initially filled with @code{C} predefined keywords. When parsing +input files, @command{cflow} updates these tables. In particular, upon +encountering a @code{typedef}, it registers the defined symbol as a +@dfn{type}. + + Now, @code{DIR} is not declared in @file{d.c}, so @command{cflow} +has no way of knowing it is a data type. So, it supposes it is a +variable. But then the input: + +@smallexample + DIR *dir; +@end smallexample + +@noindent +is parsed as an @emph{expression}, meaning ``multiply @code{DIR} by +@code{dir}''. + + There are two ways to help @command{cflow} out of this +confusion. You can either explicitely declare @code{DIR} as data type, +or let @command{cflow} run preprocessor, so it sees the contents of +the include files and determines it by itself. Running preprocessor is +covered by the next chapter (@pxref{Preprocessing}). In the present +chapter we will concentrate on the first method. + +@cindex @option{-s} introduced +@cindex @option{--symbol} introduced + Command line option @option{--symbol} (@option{-s}) declares a +type of the symbol. Its argument consists of two strings separated by +a colon: + +@smallexample + --symbol @var{sym}:@var{t} +@end smallexample + +@noindent +The first string, @var{sym} is a @code{C} identifier to be recorded in +the symbol table. The second string, @var{t}, specifies a type to +be associated with this symbol. If @var{t} is a string @samp{type}, +the symbol @var{sym} will be recorded as a @code{C} type +definition. Thus, to fix the above example, run: + +@smallexample +$ cflow --number -i x --symbol DIR:type d.c +@end smallexample + +@cindex Parameter wrapper defined +@cindex @code{__P}, special handling using @option{--symbol} + Another important symbol type is a @dfn{parameter wrapper}. It is +a kind of a macro often used in sources meant to be compatible with +pre-@acronym{ASNI} compilers to protect parameter declarations in +function prototypes. For example, in the declaration below, taken from +@file{/usr/include/resolv.h}, @code{__P} is a parameter wrapper: + +@smallexample +void res_npquery __P((const res_state, const u_char *, int, FILE *)); +@end smallexample + + For @command{cflow} to be able to process such declarations, +declare @code{__P} as a wrapper, for example: + +@smallexample +cflow --symbol __P:wrapper *.c +@end smallexample + +@cindex @code{__attribute__}, special handling using @option{--symbol} + Another usage for @code{wrapper} symbol type is to declare +special @dfn{attributes} often used with @command{gcc}. For example, +the following declaration: + +@smallexample +void fatal_exit (void) __attribute__ ((noreturn)); +@end smallexample + +@noindent +will confuse @command{cflow}. To correctly process it, use option +@option{--symbol __attribute__:wrapper}. + + For the complete list of @option{--symbol} supported types, +@FIXME-xref{symbol types}. + + Notice, finally, that when using @dfn{preprocess mode}, there is +no need to use @option{--symbol}, since in this mode @command{cflow} +is able to correctly determine all symbol types by itself. + +@node Preprocessing, Cross-References, Symbols, Top @chapter Running Preprocessor -@UNREVISED{} -@FIXME{How to run preprocessor. Differences between the two modes.} +@cindex Preprocess mode introduced +@cindex Running preprocessor +@cindex @option{--cpp} option introduced +@cindex @option{--preprocess} option introduced + @command{Cflow} can preprocess input files before analyzing them, +the same way @command{cc} does before compiling. Doing so allows +@command{cflow} to correctly process all symbol declarations, thus +avoiding the necessity to define special symbols using +@option{--symbol} option, described in the previous chapter. To enable +preprocessing, run the utility with @option{--cpp} +(@option{--preprocess}) command line option. For our sample file +@file{d.c}, this mode gives: + +@cindex @option{--cpp} option, an example +@cindex @option{--preprocess} option, an example +@smallexample +$ cflow --cpp -n d.c + 1 main() <int main (int argc,char **argv) at d.c:85>: + 2 fprintf() + 3 atoi() + 4 printdir() <void printdir (int level,char *name) at d.c:42> (R): + 5 getcwd() + 6 perror() + 7 chdir() + 8 opendir() + 9 readdir() + 10 printf() + 11 ignorent() <int ignorent (char *name) at d.c:28>: + 12 strcmp() + 13 isdir() <int isdir (char *name) at d.c:12>: + 14 stat() + 15 perror() + 16 putchar() + 17 printdir() + <void printdir (int level,char *name) at d.c:42> + (recursive: see 4) + 18 closedir() +@end smallexample -@node Symbols, Cross-References, Preprocessing, Top -@chapter Controlling Symbol Input and Output. -@UNREVISED{} -@FIXME{Controlling which symbols to display. Options --include and --symbol. -Special quirks using --symbol option. } + Compare this graph with the one obtained without @option{--cpp} +option (@pxref{sample flowchart}). As you see, it no longer contains a +reference to @code{S_ISDIR}: the macro has been expanded. Now, try +running @code{cflow --cpp --number -i x d.c} and compare the result +with the graph obtained without preprocessing (@pxref{x +flowchart}). You will see that it produces correct results without +using @option{--symbol} option. -@node Cross-References, ASCII Tree, Symbols, Top +@FIXME{To preprocess or not to preprocess?} + +@cindex Default preprocessor command +@cindex Preprocessor command, overriding the default + By default @option{--cpp} runs @file{/usr/bin/cpp}. If you wish +to run another preprocessor command, specify it as an argument to the +option, after an equal sign. For example, @command{cflow --cpp='cc +-E'} will run a @code{C} compiler as a preprocessor. + +@node Cross-References, ASCII Tree, Preprocessing, Top @chapter Cross-Reference Output. -@UNREVISED{} -@FIXME{Cross-reference output} +@cindex Cross-References introduced +@cindex @option{--xref} option introduced +@cindex @option{-x} option introduced + GNU @command{cflow} is also able to produce @dfn{cross-reference +listings}. This mode is enabled by @option{--xref} (@option{-x}) +command line option. Cross-reference output lists each symbol +occurrence on a separate line. Each line shows the identifier and the +source location where it appears. If this location is where the symbol +is defined, it is additionally marked with an asterisk and followed by +the definition. For example, here is a fragment of cross-reference +output for @file{d.c} program: + +@smallexample +printdir * d.c:42 void printdir (int level,char *name) +printdir d.c:74 +printdir d.c:102 +@end smallexample + + It shows that the function @code{printdir} is defined in line 42 +and referenced twice, in lines 74 and 102. + + The symbols included in cross-reference listings are controlled +by @option{--include} option (@pxref{--include}). In addition to +character classes discussed in chapter ``Controlling Symbol Types'' +(@pxref{Symbols}), an additional symbol class @code{t} controls +listing of type names defined by @code{typedef} keyword. @node ASCII Tree, Configuration, Cross-References, Top @chapter Using ASCII Art to Produce Flow Trees. |