/*!
\page preprocess Preprocess - A preprocessor for C and C++ modules
\ifnot man
Do you hate writing C or C++ header files?
Do you always forget where to place those inline,
virtual, static, and explicit
modifiers -- to the member-function definition or declaration?
Do you often find yourself avoiding to factor out a new method because
you also need to add a method declaration to the class declaration in
the header file?
Do you hate putting inline function into header files, in a special
order?
If so, Preprocess may be your answer. With this tool, you write
unit-style single-source-file modules in C++, from which it
automatically generates header and implementation files.
\endif
\section SYNOPSIS Synopsis
preprocess -c filename_base
[ -o outfile_base | -s]
[ -p prepend ]
[ -C source_ext ]
[ -H header_ext ]
[ -e tag_list ]
[ -i ] [ -t ]
[ -l | -L ] [ -v ] [ -d ]
sources...
\section DESCRIPTION Description
Preprocess is a preprocessor for C++ modules. With this tool, you
write unit-style single-source-file modules in C++.
Preprocess essentially does these things (and frees the programmer
from doing them):
inline" can be put
into the implementation file (out of line). This can ease
development (as it temporarily decreases dependencies on header
files that change frequently) and debugging.
\endhtmlonly
Modules contain two sections. The "INTERFACE:"
section contains the public interface to the module; the
"IMPLEMENTATION:" section contains everything else. The
preprocessor puts interface declarations into a public header file and
tries to hide everything else.
Class definitions deliberately lack declarations for member
functions: Preprocess will add them automatically. Member-function
definitions (in the implementation section) labelled
PUBLIC, PROTECTED and PRIVATE
are put into the corresponding section of the class. This feature
saves typing effort and reduces duplication.
From this input file (foo.cpp), Preprocess extracts three C++ source
files that can then be processed using the standard C++ compiler
toolchain:
\htmlonly
|
\endhtmlonly
\htmlonly
|
\endhtmlonly
First, Preprocess generates a public header file (foo.h). This
header file contains all declarations from the interface section, with
class definitions properly expanded to contain member-function
declarations\htmlonly (shown red in the
example on the right side)\endhtmlonly.
It also contains declarations of non-"static" free
functions found in the implementation section, as well as definitions
for functions declared "inline". Additionally, it
contains all "\#include" directives and function and class
declarations and definitions the inline functions need; these
dependencies need to be declared in the input file. (These features
are not shown in the example\htmlonly on the right side\endhtmlonly.)
If desired, preprocess can also be instructed to hide all inline
functions (and to generate them out-of-line instead), resulting in a
public header file that better insulates clients from implementation
details.
\htmlonly
|
\endhtmlonly
\htmlonly
|
| \endhtmlonly Second, a private header file containing all non-public type definitions (foo_i.h). This file can be used by debugging modules that need access to implementation-specific data structures. This file also contains all inline member functions belonging to classes declared here. (This feature is not shown in the example.) \htmlonly |
\endhtmlonly
\htmlonly
|
\endhtmlonly
Third, an implementation file (foo.cc). This file starts with
declarations for all free "static" functions (not shown in
the example). Otherwise, it comprises all non-inline function
definitions (and static inline functions).
\htmlonly
|
\endhtmlonly
\htmlonly
|
-suffix].source_ext.header_ext_i.header_ext-p, outfile_base needs to be
specified using -c, suffix is an optional
suffix that can be specified using the IMPLEMENTATION
directive, and source_ext and header_ext default
to ".cc" and ".h" but can be overridden using -C and
-H, respectively.
-c filename_base -o outfile_base -c option.-sIMPLEMENTATION directives in the
source files.-p prepend /").-C source_ext-H header_ext-e tag_list-s
option. See Section
\ref CONDITIONAL \if man CONDITIONAL COMPILATION \endif
for details on this option.-t \#include
directives in generated source files that are otherwise empty,
resulting in increased compilation speed for these files.-i inline code. If this option is not
given, all code (including code marked "inline")
is generated out-of-line.-l \#line directives in output
files. If this option is not given, \#line will be
generated by default.-L \#line directives in header files only.
Using this option can speed up builds because the contents of
header files change less frequently, as \#line
directives for (member) function declarations do not have to be
updated every time its definition in the source module changes
its absolute position. (Of course, this assumes that the time
stamp of header files are updated only when the contents of the
files change. See Section
\ref MAKEFILE \if man EXAMPLE MAKEFILE FRAGMENT \endif
for a possible way to
do this.) -v preprocess' parser pass.-d -e).INTERFACE:
IMPLEMENTATION sections.
\htmlonly \endhtmlonly Function definitions are not allowed in this section.
IMPLEMENTATION:
INTERFACE: sections) end up in the internal
header file -- except if a public inline function of a
public class depends on the private class, in which case
the private class' declaration will be put into the
public header file.
PUBLIC, PRIVATE, and PROTECTED
explicit, static, and virtual
inline
inline NEEDS [dependencies,
... ]
inline, but additionally specifies types,
functions, and \#include statements that this
inline function depends on and that consequently need to be
exported as well, in front of this inline function. Preprocess
reorders definitions such that all dependencies are defined
before the inline function.
\htmlonly \endhtmlonly Example:
inline NEEDS["foo.h", some_func, Some_class, Some_other_class::member_func] int foo () { }
IMPLEMENTATION [suffix]:
.cc, the code ends up in
outfile_base-suffix.cc.
This directive is useful if there are several input files that
together make up one input module (which are fed to Preprocess
at the same time and which share one public and one private
header file).
(This form of the IMPLEMENTATION directive works only if
neither the -s (no-suffix) nor the -e
(conditional compilation) options are used. See Section
\ref CONDITIONAL \if man CONDITIONAL COMPILATION \endif
for information on conditional compilation.)
EXTENSION class classname {
... };
IMPLEMENT
inline NOEXPORT
inline ALWAYS_INLINE
-i option is not used. Use this
specifier for functions that absolutely must be inline even in
debugging builds.
-e tag_list" option.
INTERFACE [tag_expression]: IMPLEMENTATION [tag_expression]:INTERFACE or IMPLEMENTATION section
is included in the output only if it is true using the
selectors specified in tag_list.
\section MISC Usage hints When you use Preprocess, there are a few things you need to keep in mind.INTERFACE [a,b]:// This section is used whenever a or b is contained in the tag_listINTERFACE [a-b]:// This section is used whenever a and b are contained in the tag_listINTERFACE [a,b-c]:// This section is used whenever a, or b and c are // contained in the tag_listINTERFACE [!a]:// This section is used whenever a is not contained in the tag_listINTERFACE [{a,b}-c]:// This section is used whenever a and c, or b and c are // contained in the tag_listINTERFACE [!a,b-c]:// This section is used whenever a is not contained in the tag_list, // or b and c are contained in the tag_list
\endhtmlonly
\#include"
the corresponding header files (or add forward declarations) in
the "INTERFACE:" section of your module. Private
inline functions (which might end up in the public header file)
need to specify their include dependencies in a "NEEDS[]"
clause.
\htmlonly \endhtmlonly
Also, if you use names declared in an (externally-defined)
namespace (such as namespace "std"), you must
specify the fully-qualified name (including the namespace) in
the function signature (unless you use a "using
namespace" directive in the "INTERFACE:"
section, which is not recommended).
\htmlonly
\endhtmlonly
NEEDS" clause.
Otherwise, Preprocess cannot guarantee the correct
inline-function order in the output, and you may get compiler
warnings like ``inline function is used but not defined.'' This
problem is reinforced when using private inline functions,
because Preprocess moves them out of the public header file
(into the private header file) unless a public function's
"NEEDS" clause requires them.
\endhtmlonly
This is an example fragment from a Makefile (for GNU Make) that
generates *.cc, *.h, and *_i.h
files on the fly. It only updates the generated files if they
actually change; that is, if you change something in the
implementation section that does not influence the header files, they
will not be updated, avoiding recompilation of files that depend on
them.
This Makefile fragment needs GNU Make and the move-if-change script that only updates a
target if it is different from the source.
This example assumes that you do not use the
IMPLEMENTATION[suffix]
directive. If you do plan using this directive, a more elaborate
mechanism is needed, such as the one used in the Makefiles for the
Fiasco microkernel.
\htmlonly
|
\endhtmlonly
|
\htmlonly
\#line directives Preprocess generates sometimes
are offset plus/minus one or two lines to the real code.
\#include and \#if 0; it just
copies all other direcitives into the output as it finds them.
That makes it easy for you to shoot yourself into the foot.
.cpp files into new
.cpp files, refactoring or renaming code on the
fly.
preprocess"
from the DROPS project's remote-CVS server. Please refer to the download
instructions on DROPS' website.
\section LIST Mailing list
There is a mailing list to which CVS-commit messages for changes made
to preprocess are posted. Please ask me if you would like to be put
on this list (see Section \ref AUTHOR \if man AUTHOR \endif).
New releases are periodically announced on the Freshmeat
website. If you are a registered Freshmeat user, you can subscribe to these
release announcements\if man at
http://freshmeat.net/subscribe/36508/\endif.
\section AUTHOR Author
Michael Hohmuth move-if-change(1) shell script\if man
: http://os.inf.tu-dresden.de/~hohmuth/prj/preprocess/move-if-change
\endif
\if man
Preprocess
project web page
: http://os.inf.tu-dresden.de/~hohmuth/prj/preprocess/
\endif
Preprocess was originally written for the Fiasco microkernel\if man
: http://os.inf.tu-dresden.de/fiasco/
\endif.
*/