How it works
------------
Gtkmmproc is a 3 pass process.
1. Parse .hg/.ccg files and generate meta m4 macros in a tmp file (e.g. gtkmmproc5466.g1)
2. run m4 to expand macro text (to get e.g. (e.g. gtkmmproc5466.g2)
3. snip file into pieces. (.h .private_h, .cc)
1.
The first pass is to escape anything which may cause problems
with m4 processing of a file. This pass is performed in perl.
It also implements meta macros which are macros in which
a C++ declaration must be broken into an argument list.
Commands marked with are implmented at this
level.
TODO: ? Is this still true? murrayc
At this point there is a file (e.g. /tmp/gtkmmproc5466.g1)
which contains text and m4 code. This m4 code is our m4
macros which will be expanded in the next pass.
2.
The second pass does both expansion and rearrangement of
code. The entire file including both the .hg headers and the
.ccg source files are processed as one piece. This is because
some macros expand into multiple sections. Commands marked
with are implemented at this level.
3.
The third pass is to take the M4 output and snip it into
the actually header and implementation files for use.
There are no commands which communicate directly with this layer,
though any raw C++ code from the .hg/.ccg files will of course be
carried through to here.
All macros are in capitals and are proceed by an underscore.
Output files
-------------
gtkmmproc generates 3 output files. One is the header for inclusion
in user code. The other is the implementation including implementing
all the macro built functions. The last is a private header. The
private header contains all the functions which are necessary to
derive a C object in the gtk+ object system from this widget.
The private header is not for user consumption.
Sectioning
-----------
Much of the magic of gtkmmproc happens at the m4 level.
This includes sectioning. Sectioning is method in which a macro
can create pieces of text after or before the expansion of the
macro. Sectioning is done with the m4 divert command.
The macros _SECTION(), _PUSH() and _POP() are used to
control what section is being writen.
It is important to understand how the sections of a class
are assembled.
Example:
something.hg:
#include
namespace Gtk {
class SomeThing
{
WRAP_CLASS(...)
public:
// my methods
void do();
};
}
something.cmm:
void Gtk::SomeThing::do() {}
This will be broken up into the following sections
<<>> represents a include section. * marks macro expansions.
(Names don't match current code look at m4 file to see what current
name is.)
something.h:
* #ifndef SOMETHING_H
* #define SOMETHING_H
#include
<>
namespace Gtk {
class SomeThing {
{
* public:
* typedef ...
* ....
public:
// my methods
void do();
<>
};
}
#endif
something.cc:
void Gtk::SomeThing::do() {}
* void gtkmm_something_init_type(
* ....
<>
<>
<>
something_p.h:
* class SomeThing_Class {
<>
* };
If you, for example, need to place something in PRIVATE for this
class, you would do
class SomeThing {
....
_SECTION(PRIVATE)
my stuff
_SECTION(CLASS)
}
In order to improve clarity the m4 template is expanded into
multiple files, one for each type of macro processed.