[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An alert reader has already noticed something strange in the
above output: the function _exit
is missing, although according
to the source file it is called twice by printdir
. It is
because by default cflow
omits from its output all symbols
beginning with underscore character. To include these symbols as well,
specify ‘-i _’ (or ‘--include _’) command line option.
Continuing our example:
$ 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()
In general, ‘--include’ takes an argument specifying a list of 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.
The symbol class ‘_’ includes symbols whose names begin with an
underscore. Another useful symbol class is ‘s’, representing
static functions or data. By default, static functions are
always included in the output. To omit them, one can give
‘-i ^s’ (or ‘-i -s’(4))
command line option. Our sample program ‘d.c’ defines static
function isdir
, running cflow -i ^s
, completely omits
this function and its callees from the resulting graph:
$ 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()
Actually, the exclusion sign (‘^’ or ‘-’) can be used any place in ‘-i’ argument, not only at the beginning. Thus, option ‘-i _^s’ means “include symbols, beginning with underscore and exclude static functions”. Several ‘-i’ options accumulate, so the previous example can also be written as ‘-i _ -i ^s’.
It is important to notice that by default cflow
graphs
contain only functions. You can, however, request displaying variables
as well, by using symbol class ‘x’. This class contains all data
symbols, both global and static, so to include these in the output,
use option ‘-i x’. For example:
$ cflow --number -i x d.c 1 main() <int main (int argc,char **argv) at d.c:85>: 2 fprintf() 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: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 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()
Now, lines 3, 4, 16 and 23 show data symbols, with their
definitions when available. Notice, however, lines 7 and 8. Why both
type name DIR
and automatic variable dir
are listed as
data?
To answer this question, let’s first describe the cflow
notion of symbols. The program keeps its symbol tables, which
are initially filled with C
predefined keywords. When parsing
input files, cflow
updates these tables. In particular, upon
encountering a typedef
, it registers the defined symbol as a
type.
Now, DIR
is not declared in ‘d.c’, so cflow
has no way of knowing it is a data type. So, it supposes it is a
variable. But then the input:
DIR *dir;
is parsed as an expression, meaning “multiply DIR
by
dir
”.
Of course, it is wrong. There are two ways to help
cflow
out of this confusion. You can either explicitly
declare DIR
as data type, or let 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 (see section Running Preprocessor). In the present chapter we will
concentrate on the first method.
The command line option ‘--symbol’ (‘-s’) declares a syntactic class of the symbol. Its argument consists of two strings separated by a colon:
--symbol sym:class
The first string, sym is a C
identifier to be recorded in
the symbol table. The second string, class, specifies a class to
be associated with this symbol. In particular, if class is
‘type’, the symbol sym will be recorded as a C
type
definition. Thus, to fix the above output, run:
$ cflow --number -i x --symbol DIR:type d.c
Another important symbol type is a parameter wrapper. It is
a kind of a macro, often used in sources that are meant to be
compatible with pre-ANSI compilers to protect parameter
declarations in function prototypes. For example, in the declaration
below, taken from ‘/usr/include/resolv.h’, __P
is a
parameter wrapper:
void res_npquery __P((const res_state, const u_char *, int, FILE *));
For cflow
to be able to process such declarations,
declare __P
as a wrapper, for example:
cflow --symbol __P:wrapper *.c
In both examples above the reason for using the
‘--symbol’ option was that cflow
was unable to
determine what the given symbol was, either because it did not
see the type definition, as it was in case with ‘DIR’, or
because the macro definition was not expanded. Both cases are better
solved by using preprocess mode, described in the next
chapter. Nevertheless, even with preprocessor, the
‘--symbol’ option remains useful, as shown in the following
sections.
6.1 Syntactic classes | ||
6.2 Symbol aliases | ||
6.3 GCC Initialization |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] |
This document was generated on December 30, 2021 using texi2html 5.0.