aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--doc/cflow.texi381
2 files changed, 329 insertions, 60 deletions
diff --git a/ChangeLog b/ChangeLog
index 84c3403..bd48ce8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.

Return to:

Send suggestions and report system problems to the System administrator.