Cfunctions and this manual are copyright (C) 1998 Ben K. Bullock. Some parts of the Cfunctions distribution, the files in the subdirectory `missing', are copyright (C) 1997 by the Free Software Foundation (see the actual files for details).
Cfunctions, and this manual, are free software under the GNU General Public Licence (otherwise known as the GNU GPL or just the GPL. The GNU General Public Licence is in the file `COPYING' in the Cfunctions distribution directory. The GNU General Public Licence does not apply to the output of Cfunctions. The file `c-extensions.h', which is used with Cfunctions, is licenced differently. Please refer to that file for more information.
Because of the small size of this manual the GNU General Public Licence is not included.
You can find the GNU General Public License at The Free Software Foundation .This is the manual for Cfunctions version @version {}. This manual explains Cfunctions, a program for making header files from C files. Cfunctions (pronounced "see-functions") gets function declarations, prototypes and global (otherwise known as external) variable declarations from C files and makes them into header files.
Here are some simple examples of how to run Cfunctions. If you have already compiled the program, you might like to try it out on some C files using the following examples as a template.
cfunctions a.c b.c c.cwrites the function and global variable declarations in the three C files to standard output.
cfunctions -i a.c b.c c.ccreates three files `a.h', `b.h' and `c.h' containing the function and global variable declarations of the three C files.
cfunctions -g everything a.c b.c c.ccreates a header file called `everything.h' which contains all the function and global variable declarations of the three C files.
This section gives some examples that you can type in to Cfunctions using it as a pipe, reading standard input.
Input some C to Cfunctions, for example
int func (int y) { return 0; }
and Cfunctions outputs
int func (int y);
the function declaration. Now try
int z;
Cfunctions outputs
extern int z;
This is a declaration of the variable z suitable for use in a header file. Now input
extern int z;
to Cfunctions. Cfunctions outputs nothing, because extern
means
z was declared elsewhere, so it should not be declared in a header
file. Now input
static int q; static char * tub (int jub) { return array[ jub ]; }
Cfunctions outputs nothing. That is because both q and
tub are declared with static
. Cfunctions assumes that it
is writing a header file, so it doesn't output anything declared
static
.
Now, try cfunctions --wrap chap
, with input
int s, t, u; char * func() { return "junk"; }
Cfunctions outputs
#ifndef _CHAP #define _CHAP extern int s, t, u; char * func(); #endif /* _CHAP */
because the -w chap
option requested a wrapper See section Wrappers.
This is already enough to declare the external variables and functions
in the input file and write them out to a header file.
Cfunctions can be configured with a file `.cfunctionsrc' in your home directory. The possible command-line and configuration options for Cfunctions are
-a argument
--advert argument
-b
--backup
-c
--copy-c-ex
-C
--cpp
-D argument
--debug argument
-e
--etags
-g argument
--global argument
-G argument
--global-macro argument
-h
--help
-I
--include-c-ex
-i
--individual
-k
--keep
-l argument
--local argument
-L argument
--local-macro argument
-m
--write-comments
-n
--line-numbers
-o argument
--output argument
-P argument
--cpp-arg argument
-p argument
--proto-macro argument
-s
--static
static
.
-S argument
--suffix argument
-t
--tags
-v
--version
-V argument
--version-control argument
-W argument
--warn argument
-w argument
--wrap argument
-x
--extensions
This chapter explains how to make Cfunctions generate correct variable and function declarations.
Cfunctions gets global variables from C files and writes them with an
extern
prefix. For example,
int x;
becomes
extern int x;
It does not prefix functions with extern
, because there is no
point in doing so.
struct
, union
, and enum
Cfunctions writes out struct
, union
and enum
declarations by copying the declaration. For example
struct bee gee;
becomes
extern struct bee gee;
in Cfunctions's output.
struct
, union
, enum
body
Cfunctions does not write the
body (part between { and }) of union
s, struct
s and
enum
s.
Even if the declaration of a variable contains a definition of a data
structure, Cfunctions does not write the data structure's definition.
For example,
struct heeby { int x, y; unsigned z; } geeby;
becomes
extern struct heeby geeby;
which will not be understandable to compilers, because struct
heeby
was not declared: you will get an error message about the
`incomplete type'. To avoid this problem, declare structure instances
such as geeby
in the above with static
so that Cfunctions
ignores them. When you want a global instance of a structure like
geeby
, ask Cfunctions to copy the body as well.
See section Extra header information.
struct
sCfunctions ignores untagged structures such as
struct {int a} d;
except when copying verbatim. See section Extra header information.
typedef
Cfunctions ignores typedef
statements except when copying
verbatim. See section Extra header information.
Cfunctions outputs one dimensional array declarations with the array's size removed. For example,
int mung[N_MUNG];
becomes
extern int mung[];
However C does not allow multidimensional arrays with any but the first dimension removed. Therefore for example Cfunctions writes
int mung_sq[N_MUNG][N_MUNG];
as
extern int mung_sq[][N_MUNG];
N_MUNG
might be a macro defined only in the C file Cfunctions
read the declaration from, and the C compiler would choke on this
declaration. Cfunctions does not check that an array's dimensions are
valid, it merely copies them, so users must use array dimensions which
remain valid in the header file.
static
Cfunctions usually ignores static
functions and variables
. To make forward declarations for static
C functions, or to
make a tag table which includes them, use the --static
(-s
) option.
Cfunctions can also make prototype declarations for traditional C files. (Traditional C is the language described in edition 1 of Kernighan and Ritchie's book `The C programming language'.) For traditional C files, Cfunctions writes a macro around the prototype function arguments. You then have to define this macro to give either prototype arguments (for an ANSI C compiler) or nothing (for a traditional C compiler). For example
int func (x, y, v) unsigned long y; char * v; { ...
becomes
int func PROTO((/* default */ int x, unsigned long y, char * v));
Then for the traditional case PROTO
is defined as
#define PROTO(x) ()
and for the ANSI C case PROTO
is defined
as
#define PROTO(x) x
which in the above example gives you either
int func (); /* traditional */
or
int func (/* default */ int x, unsigned long y, char * v); /* ANSI */
By default the macro is called PROTO
, but you can change the
macro name to xxx with the --proto-macro xxx
(-pxxx
) option.
The macro PROTO
is defined in `c-extensions.h' (see section Input file format). If you change the macro name, you also need to ensure
that your new macro name is defined.
If you always want to use a different prototype name such as xxx, add a line containing the name, such as
proto macro: xxx
to a file called `.cfunctionsrc' in your top level or home directory.
To copy the comments in the C file into the header file, use the
--write-comments
(-m
) option. This makes Cfunctions copy
the most recently read comment verbatim into the output whenever it
writes a declaration.
Cfunctions understands C++ style //
comments.
GNU C allows C++ style comments
and they are quite commonly used in C files, so Cfunctions is able to
understand them.
Cfunctions can warn about some kinds of problems in the input files.
These warnings are optional. To get the warnings, use the
--warning
(-W
) option together with one of the following:
implicit
int
functions and function arguments.
implicit-int
implicit
reserved
strict-prototypes
Some of the warning names are based on those of GNU C, but the things that Cfunctions warns about are not the same things as the warnings of GNU C.
If you always want to be warned about any of the above practices, put a line such as
warn: implicit strict-prototypes
to a file called `.cfunctionsrc' in your top level or home directory.
You can invoke Cfunctions with a list of C files as arguments. Without
arguments, Cfunctions reads from standard input and writes to standard
output. You can redirect this with the --output argument
(-oargument
) command line option, where argument is
the name of the output file.
To write information from several C files into one header file, use the
command line option --global argument
(-gargument
). The argument is the base name of the
header file. For example,
cfunctions --global x a.c b.c c.c
will generate a header file called `x.h' containing information from `a.c', `b.c' and `c.c'.
To include extra information in the global header which is not in any of
the C files, create a file called `name.hin' where
name is the argument to --global
. Cfunctions copies
verbatim the contents of this file after the beginning wrapper
(see section Wrappers).
The option --individual
(-i
) makes Cfunctions write a
separate header file for each C file argument. The name of the header
file is the C file name with an `.h' suffix instead of `.c'.
For example,
cfunctions -i jub.c hub.c
creates `jub.h' and `hub.h'.
To generate both `local' headers for each C file and a global header,
use the --individual
and --global
options together in
conjunction with LOCAL
and LOCAL_H
directives in your C
files. See section Making `local' headers.
Cfunctions does not change C files, but it may overwrite files with a
`.h' suffix. The option --backup
makes Cfunctions rename
old files rather than overwrite them.
If one uses this option, Cfunctions usually renames old files with a
~
suffix. You can change the suffix with the command line option
--suffix argument
(-Sargument
) where
argument is the suffix to use, or by the environment variable
SIMPLE_BACKUP_SUFFIX
. Numbered backups are also possible. The
command line option --version-control argument
(-V
argument
) switches this on. The possible values of
argument are
t, numbered
nil, existing
never, simple
Putting the same strings into the environment variable
VERSION_CONTROL
has the same effect, and also causes the same
behaviour in GNU programs such as Emacs, Indent, Patch, and the GNU
fileutils.
Refer to, for example, the GNU Emacs manual, section `Backup Names', for
more details.
Cfunctions usually advertises itself at the top of generated files. To
turn this advertisement off, use the option --advert off
(-aoff
). To substitute another banner, use --advert
file-name where file-name is the name of the file
containing your information. Cfunctions will copy it verbatim, so don't
forget to put text inside C comments.
If you always want to put the same text at the top of each generated header file, add a line containing the file you wish to have copied, such as
advert: /home/me/mydirectory/mycopyright
to a file called `.cfunctionsrc' in your top level or home directory.
Cfunctions usually writes a `wrapper' around header files so that they
will not be read twice.
For example, cfunctions -i jub.c
will generate
#ifndef CFH_JUB_H #define CFH_JUB_H ... #endif /* CFH_JUB_H */
Cfunctions does not write wrappers when writing to standard output. To
force wrappers, use the option --wrap argument
(-w
argument
). Cfunctions converts argument to upper case
and removes bad characters, and then uses it as the macro, CFH_JUB_H
in the above example.
A tag table is an index of functions and external variables. The reason
that Cfunctions also makes this file is that a tag table for a C file
consists of a list of global variables and function definitions,
although in a different format to a header file. The tag table also
includes type definitions, data structures, C unions and enumeration
constants.
Cfunctions understands #line
instructions and it will adjust the
tag table output accordingly.
Cfunctions does not preserve decorative spacing. Cfunctions uses only a single space for all spacing within a particular prototype. In fact, Cfunctions has no facilities for formatting its output to a particular taste. To reformat the generated header files according to your tastes, use an indenting program such as GNU indent.
Cfunctions does not require any particular C file format. However some extra facilities of Cfunctions require formatted input files. The formats do not affect compilation. The formats are designed so that Cfunctions never needs to alter C files.
If you use Cfunctions's special features, Cfunctions automatically writes
#include "c-extensions.h"
into your generated header file. The file `c-extensions.h' contains definitions of macros which make the special features such as C extensions work both with compilers with the C extensions, and without them.
Cfunctions also usually copies the file itself into the current
directory. You can prevent this with the --extension
(-x
)
option.
If you prefer the following type of statement,
#include <c-extensions.h>
use the --include-c-ex
(-I
) command line option. In this
case Cfunctions will never copy the file into the current directory,
since that would be useless: you should instruct the C compiler where to
find the file (this may be with the -I
option, hence the short
option name in Cfunctions is mnemonic).
Note that the file `c-extensions.h' is not under the GNU General Public Licence. It does not have any restrictions on its use. Whatever licencing terms your program is under, you can incorporate `c-extensions.h' into it.
Cfunctions understands several GNU C extensions. See Info file `gcc.info', node `C extensions', to find out about the GNU C extensions. The following prefixes to functions get GNU C extensions in the generated header file:
NO_RETURN
__attribute__((noreturn))
suffix in the prototype.
It is a macro defined to void
.
NO_SIDE_FX
__attribute__((const))
suffix to the
prototype. It is an empty macro.
INLINE
PRINT_FORMAT(a,b)
__attribute__((format(printf,a,b)))
suffix in the prototype. It is an empty macro.
To include material directly into the header file, surround it with
#ifdef HEADER ... #endif
. For example,
#ifdef HEADER typedef struct dictionary Dictionary; #endif
Cfunctions just copies everything between the #ifdef
and the
#endif
into the header file. Because a macro HEADER
is
not usually defined, the C compiler ignores this material in the C file.
(If by chance a macro HEADER
is already defined, change
the macro name Cfunctions recognizes with the --global-macro
argument
(-Gargument
) option, where
argument is a macro name to use instead of HEADER
.)
When using the --global
option, you may want to share some
function declarations only with a few specific files. For example,
suppose that a library lib
is created from jub.c
and
hub.c
but that only hub.c
should use the function
private
from jub.c
, not lib
library users. To hide
the private
function by not putting its prototype into the
library header lib.h
, make a local header for jub.c
by
cfunctions -g lib -i jub.c hub.c
This creates jub.h
and hub.h
as well as lib.h
. To
make the prototype of private
appear in jub.h
and not in
lib.h
, prefix private
with LOCAL
, and the prototype
for private
will appear in `jub.h'. LOCAL
is a C
macro defined to nothing by the `c-extensions.h' header file
(see section C extensions).
To make just one `local' header file to share between `jub.c' and `hub.c' use
cfunctions -g lib -l private jub.c hub.c
This will create files `lib.h' and `private.h'. The
declaration of private
will go into `private.h' and not into
`lib.h'.
To include information verbatim into a local header file use
LOCAL_H
preprocessor wrapper in the same way as #ifdef
HEADER
(see section Extra header information)
If by chance a macro LOCAL_H
is already defined, change the name
LOCAL_H
used for the wrapper with the option --local-macro
argument
, where argument is the name of the new macro.
The option --local argument
(-largument
)
sends all the `local' header output from each C file to one header file
instead of several. Contrast this with --individual
(-i
)
which generates several header files, one for each input C file. The
argument is the base name of the local header file.
In GNU C, a function can be declared inline
.
Refer to the GNU C manual for details.
However, GNU C cannot `inline' a function in a separate translation unit
from the function body. To work around this restriction, Cfunctions can
copy the entire function to a header file so that it can be used over
several translation units. It uses the special GNU C prefix
extern inline
and a wrapper so as not to confuse other compilers.
To get Cfunctions to do this, prefix the function with Cfunctions's
keyword INLINE
and run Cfunctions. For example,
INLINE int square (int i) { return i*i; }
generates
#ifdef X_INLINE extern inline int square (int i) { return i*i; } #else /* not X_INLINE */ int square (int i); #endif /* X_INLINE */
in the output header file. Cfunctions's special header file
`c-extensions.h' defines the macro X_INLINE
for GNU C, but
not for other C compilers and it defines the macro INLINE
to
nothing, so as not to cause portability problems.
This chapter explains some subtleties of using Cfunctions with other programs.
make
It is possible to use Cfunctions to generate header files with make
.
There are two ways to do this. One way is to write explicit rules for
generating header files in a `Makefile'. For example,
jubs.h: jubs.c cfunctions --individual jubs.c
Another way is to teach make
a rule for making header files from C
files.
.c.h: cfunctions --individual $<
The disadvantage of the rule method is that it might fool make
into making a header file when not required, or even overwriting a
non-Cfunctions header file. You definitely should not use this unless
all your header files are generated by Cfunctions, and if you do use it,
I recommend you to use --backup
as well.
When using this kind of rule, a harmless but odd thing will occur. If
Cfunctions sees that it has generated a new header file identical to an
old one, it keeps the old one and discards the new one. When this
happens, make
runs Cfunctions again the next time. This might
seem like an error, but it is a feature. If Cfunctions did update a
header file even when it was identical to an old one, make
would
then recompile every dependency of that header file (in other words it
would recompile all the C files which #include
d the header file).
This would be inconvenient: Cfunctions runs much faster than a C
compiler, so it is less inconvenient to run Cfunctions uselessly than to
force useless recompilation.
There are some coding practices with the C preprocessor which Cfunctions
cannot cope with. Either avoid these coding practices or send
Cfunctions the output of the C preprocessor by using the --cpp
(-C
) option. With this option, you can pass arguments to the
preprocessor with the --cpp-arg
(-P
) argument. For
example
cfunctions -C -P -DGUBBINS
will send the C preprocessor the argument -DGUBBINS
.
Cfunctions cannot possibly process C code which uses macros like
#define begin {
Some people write function declarations as follows:
#if ANSI int options (int argc, char ** argv) #else int options (argc, argv) int argc; char ** argv; #endif
This is not necessary, unless your program needs to be compilable by C++ as well as traditional C compilers. ANSI C allows you to write function declarations in either way. Cfunctions cannot currently understand the above syntax, so if you need backwards compatibility just use the old-style function declaration on its own.
Some people declare functions via the preprocessor for the sake of
convenience. Unfortunately Cfunctions can't parse these functions
unless you use the -C
option.
If there is an error in a header file generated by Cfunctions, the compiler usually writes a message which refers to the line number and file name of the header file. Because the error is actually in the original C file, this is inconvenient.
To make compiler messages refer to lines in a C file and not in a
Cfunctions generated header file, use the --write-line-numbers
(-n
) option. Cfunctions will generate compiler directives of the
form
#line number "file.c"
just before it writes each declaration. Here number is the line number of the C file `file.c' that the function or variable came from. The line numbers may be slightly off, because Cfunctions does not preserve the decorative spacing (see section Spacing). However, along, with the compiler message they should be enough to indicate where problems lie.
Particularly this is useful with the GNU Emacs `compile-mode' to go to the lines in the original C file which contain the errors.
Unfortunately this will force Cfunctions to update your header file every time that it is slightly changed, causing possible unnecessary recompilations of associated files.
If you always want to write line numbers in generated header files, add the line
line numbers: 1
to a file `.cfunctionsrc' in your top level directory.
`fake-cfunctions' is a fake version of Cfunctions which uses `touch' to update header files. The reason for having this is so that one can distribute programs using Cfunctions with `make' rules for generating header files, without getting user complaints. For example in Cfunctions's `configure.in' script for GNU Autoconf there is a test for Cfunctions as follows:
CWD=`pwd` AC_CHECK_PROG(CFUNCTIONS, cfunctions, cfunctions, "$CWD/fake-cfunctions")
then in each `Makefile.in' there is a variable CFUNCTIONS
which the `configure' script fills in:
CFUNCTIONS = @CFUNCTIONS@
In the case that the user doesn't have Cfunctions installed, `configure' writes something like (assuming the current working directory is `/tmp/cfunctions-0.24')
CFUNCTIONS = /tmp/cfunctions-0.24/fake-cfunctions
whereas if the user does have Cfunctions, `configure' writes
CFUNCTIONS = cfunctions
`fake-cfunctions' just updates the file's modification time with `touch' in order to fool `make', so it won't work if the user makes major modifications to the C files, but in that case the user should get Cfunctions.
Please note that the `fake-cfunctions' script is not under the GNU GPL and you may use it whatever your licence terms are.
Jump to: # - - - . - / - _ - a - b - c - d - e - f - g - h - i - k - l - m - n - o - p - r - s - t - u - v - w
#ifdef HEADER
#ifdef LOCAL_H
#line
instructions
--advert
--backup
--copy-c-ex
--cpp
--cpp-arg
--debug
--etags
--extensions
--global
--global-macro
--help
--include-c-ex
--individual
--keep
--line-numbers
--local
--local-macro
--output
--proto-macro
--static
--suffix
--tags
--version
--version-control
--warn
--wrap
--write-comments
-a
-b
-C
-c
-D
-e
-g
-G
-h
-I
-i
-k
-L
-l
-m
-n
-o
-P
-p
-S
-s
-t
-V
-v
-w
-W
-x
//
__attribute__((const))
__attribute__((format(printf,a,b)))
__attribute__((noreturn))
begin
macro
struct
, union
cpp
enum
extern inline
extern
prefix for global variables.
HEADER
INLINE
inline
in GNU C
LOCAL
prefix
LOCAL_H
macro
NO_RETURN
NO_SIDE_FX
PRINT_FORMAT
PROTO
SIMPLE_BACKUP_SUFFIX
environment variable
static
, ignored
struct
struct
body
struct
, parts copied into header
struct
, untagged
typedef
union
struct
VERSION_CONTROL
environment variable
This document was generated on 20 November 1998 using the texi2html translator version 1.52.