GOB \- The GTK+ Object Builder
.SH SYNOPSIS
.PP
-.B gob [-?] [-h] [-w] [--exit-on-warn] [--no-exit-on-warn] [--for-cpp]
-[--no-touch-headers] file
+.B gob [-?] [-h] [--help] [--version] [-w] [--exit-on-warn]
+[--no-exit-on-warn] [--for-cpp] [--no-gnu] [--always-private-header]
+[--no-private-header] [--no-touch-headers] file
.SH DESCRIPTION
.PP
GTK+ Object Builder is a simple preprocessor for easily creating
.B -?
.TP
.B -h
+.TP
+.B --help
Display a simple help screen.
.TP
+.B --version
+Display version information (note, --version was not added until 0.92.0)
+.TP
.B -w
.TP
.B --exit-on-warn
-Exit with an errorcode even when you encounter a warning.
+Exit with an error code even when you encounter a warning.
.TP
.B --no-exit-on-warn
Exit with an error only on errors, not on warnings, this is the default.
.B --for-cpp
Generate C++ code.
.TP
+.B --no-extern-c
+Never add the extern "C" to the header.
+.TP
+.B --no-gnu
+Never generate any code with GNU C extensions. However all the GNU C
+extensions are always wrapped in #ifdef __GNUC__, so code using them compiles
+correctly even on non-GNU compilers. This option is for purists only.
+(using GNU extensions some warnings are eliminated, some ugly hacks and there
+is better argument type safety, so it's good to use them)
+.TP
.B --no-touch-headers
Don't touch the generated header file unless it really changed, this avoids
spurious rebuilds, but can confuse some make systems (automake in particular),
-so it is not enabled by default.
-
+so it is not enabled by default. Private header is still touched even if
+unchanged however.
+.TP
+.B --always-private-header
+Always create a \fB<basename>-private.h\fR file, even if it would be empty.
+Otherwise, it is only created when there are private data members in the class.
+This option implicitly negates --no-private-header
+.TP
+.B --no-private-header
+Never create a private header file. If we use any private data members,
+define the private data structure at the point in the .c source where
+the class definition begins. This option implicitly negates
+--always-private-header
.SH TYPENAMES
.PP
.PP
The filenames are created from the typename. The words are
separated by '-' and all in lower case. For example for an object named
-"Gtk:New:Button", the files are gtk-new-button.c and gtk-new-button.h.
-The header file is created to be human readable and to be used as a
+"Gtk:New:Button", the files are \fBgtk-new-button.c\fR and
+\fBgtk-new-button.h\fR.
+If you are using C++ mode, the output .c file will in fact be a .cc file.
+If you have any private data members, a private header file will also
+be created, called \fB<basename>-private.h\fR (for the example above it
+would be gtk-new-button-private.h).
+The public header file is created to be human readable and to be used as a
reference to the object. The .c source file is not created as a human
readable source and is littered with #line statements, which make the
compiler attempt to point you to the right line in your .gob file in
-case of parsing errors. The output should not be editted by hand, and
+case of parsing errors. The output should not be edited by hand, and
you should only edit the .gob file.
.SH INCLUDING NORMAL C CODE IN THE OUTPUT FILES
.PP
To include some code directly in the output C file begin with '%{'
-on an empty line and end the code with a '%}' on an empty line. To
-put the code in the output header file, start the code with a '%h{'.
-For example:
+on an empty line and end the code with a '%}' on an empty line. These
+sections will appear in the output files in the order they are given.
+There are several other \fIsections\fR to which you can put code. You can
+put it in the 'header' section (which can be abbreviated 'h') and it will
+go into the public header file. You can also put it in the 'privateheader'
+section (abbreviated 'ph') which will make the code go into the private
+header file. Sometimes you want some code (other includes) to appear before
+the extern "C" and the protecting define. To do this you can put them
+into the 'headertop' (or 'ht') section. For example:
.nf
+ %headertop{
+ /* this will be on top of the public header */
+ %}
+
+ %privateheader{
+ /* this will go into the private header file */
+ %}
+
%h{
/* will be included in the header */
void somefunc(int i);
.fi
+.SH INCLUDE FILES
+.PP
+Gob will automatically include the class header file at the top of the .c
+source file. If you wish to include it somewhere else, put the include
+into some %{ %} section above the class definition, and gob will not include
+it automatically. This way you can avoid circular includes and control
+where in the file do you want to include the header.
+.PP
+If you made any data members private, gob will also create a source file
+that will be called \fB<basename>-private.h\fR. Same rule as above applies
+for this just as it does for the regular header file. If you do explicitly
+include the regular header file, you should always include this private
+header file below it. That is, if you use any private data members. If you
+don't, the private header file automatically includes the public header file,
+and thus the public header file will be indirectly included at the very top
+of the file.
+
.SH MAKING A NEW CLASS
.PP
The class header:
.PP
Data members:
.PP
-There are three types of data members. Two of them are normal
-data numbers, and one is a virtual one, usually linked to a normal public
-data member. The two normal data members are public or private. They are
-basically just copied into the object directly. There is only one
+There are four types of data members. Three of them are normal
+data numbers, and one is a virtual one, usually linked to a normal
+data member. The three normal data members are public, protected and
+private. Public and protected are basically just entries in the object
+structure, while private has it's own dynamically allocated private
+structure. Protected members are always put after the public one in the
+structure and are marked protected in the header file. There is only one
identifier allowed per typename unlike in normal C. Example:
.nf
public int i;
private GtkWidget *h;
+ protected long k;
+
+.fi
+.PP
+Public and protected data members are accessed normally as members of
+the object struct. Example where 'i' is as above a public data member:
+.nf
+
+ object->i = 1;
.fi
.PP
-The private members are not currently protected from outside use,
-they are just marked by a comment in the header file, this will most likely
-be somehow solved in some future version.
+The private data members are defined in a structure which is only available
+inside the .c file, or by including a private header file. You must access
+them using the structure _priv. Example
+where 'h' is the private data member (as in the above example):
+.nf
+
+ object->_priv->h = NULL;
+
+.fi
+The _priv structure is defined in the \fB<basename>-private.h\fR.
+This file is automatically included if you don't include it yourself. You
+should always explicitly include it if you explicitly also include the main
+header file.
.PP
-The third type is an argument type. It is a named datamember which
+In case you use the \fB--no-private-header\fR option, no
+private header file is created and you can only access the _priv pointer
+below the class definition in the .gob file.
+.PP
+The fourth type is an argument type. It is a named data member which
is one of the features of the GTK+ object system. You need to define a get
and a set handler. They are fragments of C code that will be used to
get the value or set the value of the argument. Inside them you can use the
.fi
.PP
-If you don't define a set or a get handler it will be a readonly
-or a writeonly argument. If you want to add extra argument flags, add
+If you don't define a set or a get handler it will be a read-only
+or a write-only argument. If you want to add extra argument flags, add
them into parenthesis after the argument keyword, separated by '|' and
without the GTK_ARG_ prefix. For example:
.nf
public int height;
argument (CONSTRUCT) INT height get { ARG = self->height; };
+.fi
+This makes the argument settable even before the object is constructed, so
+that people can pass it to gtk_object_new function. Useful is also
+CONSTRUCT_ONLY flag which makes the argument only available during
+construction of the object.
+.PP
+Since 0.92.1, gob creates macros which can be used for type safe access to
+gtk arguments. The macros are called <type>_ARG_<argument name>(x) and
+<type>_GET_ARG_<argument name>(x). They define both the string and the
+value part of the argument. So for setting an argument of height, one would
+use (for object type My:Object):
+.nf
+
+ gtk_object_set(GTK_OBJECT(object),
+ MY_OBJECT_ARG_HEIGHT(7),
+ NULL);
+
+.fi
+And for getting, you would use:
+.nf
+
+ int height;
+ gtk_object_set(GTK_OBJECT(object),
+ MY_OBJECT_GET_ARG_HEIGHT(&height),
+ NULL);
+
+.fi
+Note however that the type safety only works completely on GNU C compilers.
+The code will compile on other compilers but with minimal type safety.
+.PP
+To get good type safety on POINTER types however, you should specify
+an optional C type that gob should use. For other then POINTER types
+this is redundant but possible. To do this, place '(type <c type>)'
+right after the GTK+ type. Example:
+.nf
+
+ argument POINTER (type char *) foo set { /* foo */ } get { /* bar */ };
+
.fi
.PP
Methods:
.PP
-There is a whole array of possible methods. The two normal,
-"familiar" method types are private and public. Public are defined as
-normal functions with a prototype in the header file. Private methods
+There is a whole array of possible methods. The three normal,
+"familiar" method types are private, protected and public. Public are
+defined as normal functions with a prototype in the header file.
+Protected methods are defined as normal methods (which you can call from other
+files), but their prototype is placed in the private header file. Private
+methods
are defined as static functions with prototypes at the top of the .c
-file. Then there are signal, virtual and override methods. You can also
-define init and init_class methods with a special definition if you want
+file. Then there are signal, virtual and override methods. More on those
+later. You can also
+define init and class_init methods with a special definition if you want
to add code to the constructors or you can just leave them out.
+You can also not define a body for a method, by just using ';' instead of a
+body. This will define an empty function. You can't do this for non-void
+regular public, private or protected methods, however it is acceptable for
+non-void virtual, signal and override methods.
.PP
Argument lists:
.PP
-For all but the init and init_class methods, you use the
+For all but the init and class_init methods, you use the
following syntax for arguments. The first argument can be just "self",
which gob will translate into a pointer to the object instance. The rest
of the arguments are very similar to normal C arguments. If the
something else then you can specify an "onerror" keyword after the
prototype and after that a number, a token (an identifier) or a bit of C
code enclosed in braces {}. The braces will not be printed into the
-output, they just delimit the string. For example
+output, they just delimit the string. For example:
.nf
public void * get_something(self, int i (check >= 0)) onerror NULL {
}
.fi
+The onerror value is also used in overrides that have a return value, in
+case there isn't a parent method, PARENT_HANDLER will return it. More about
+this later.
+.PP
+Constructor methods:
+.PP
+There are two methods that handle the construction of an object, init and
+class_init. You define them by just using the init or class_init keyword
+with an untyped argument in the argument list. The argument will be
+usable in your function as a pointer to your object or class depending if
+it's init or class_init.
+For example:
+.nf
+
+ init(object) {
+ /* initialize the object here */
+ object->a = 9;
+ object->b = 9;
+ }
+
+ class_init(class) {
+ /* initialize the class, this is rarely needed */
+ class->blah = NULL;
+ }
+
+.fi
+The class_init function is very rarely needed as all standard class
+initialization is taken care of for you by gob itself. The init function
+should on the other hand be used whenever you need to construct or initialize
+anything in the object to put it into a sane state. Sometimes you need
+some arguments, for this you should either use a construct method and a
+new function like many GTK+ widgets, and/or a CONSTRUCT or CONSTRUCT_ONLY
+type of an argument.
.PP
Virtual methods:
.PP
which makes calling the methods he same as public methods. This type of
method is just a little bit "slower" then normal functions, but not as
slow as signals. You define them by using "virtual" keyword before the
-prototype. If you put the keyword "private" right after the "virtual"
+prototype. If you put the keyword "private" right after the "virtual"
keyword, the wrapper will not be a public method, but a private one.
+You can do the same with "protected" to make a protected wrapper.
.PP
Signals:
.PP
.fi
.PP
If you don't want the wrapper that emits the signal to be public, you can
-include the keyword "private" after the "signal" keyword. This will make
-the wrapper a normal private method.
+include the keyword "private" after the "signal" keyword. This will make
+the wrapper a normal private method. You can also make a protected wrapper
+by using "protected" instead of "private".
.PP
If you don't define a "first" or a "last", the default will be taken as
"last".
/* some code here */
PARENT_HANDLER(self, wid);
}
+
.fi
+If the function has a return value, then PARENT_HANDLER is an expression that
+you can use. It will return whatever the parent handler returned, or the
+"onerror" expression if there was no parent handler.
.PP
Calling methods:
.PP
will fetch a new object, so a fairly standard new method would look like:
.nf
- public GtkWidget *
+ public GtkObject *
new(void) {
GtkObject *ret;
ret = GTK_OBJECT (GET_NEW);
}
.fi
+.PP
+
+.SH DEALING WITH DIFFERENT GOB VERSIONS
+.PP
+Defines:
+.PP
+In your generated C file, you can use the defines GOB_VERSION_MAJOR
+GOB_VERSION_MINOR and GOB_VERSION_PATCHLEVEL if you wish to for example
+use a feature that is only available in some newer gob version. Note however
+that you can only use these defines in the C code portions of your .gob file,
+and #ifdef's cannot span multiple functions. Check the BUGS section
+for more on using the C preprocessor and gob. Also note that these
+have only been available since the 0.92.1 version of gob.
+.PP
+Minimum version requires:
+.PP
+You can also make your .gob file require at least certain version of gob. You
+do this by putting 'requires x.y.z' (where x.y.z is the version number) outside
+of any C block, comment or class, usually you should make this the first line
+in the file or close to the top. If gob finds this and the version of gob used
+to compile the code is lower then that listed in the require, gob will generate
+an error and exit. For example to require that gob version 0.92.1 or higher
+be used to compile a file, put this at the top of that file:
+.nf
+
+ requires 0.92.1
+
+.fi
+It should be noted however that this feature was not added until 0.92.1, and
+so if the file gets compiled by a lower version, gob would generate a
+syntax error. Thus by putting in a requires line, you are implicitly
+requiring at least 0.92.1.
.SH C++ MODE
.PP
There is a C++ mode so that gob creates C++ compiler friendly files. You need
to use the --for-cpp argument to gob. This will make the generated file have
-a .cc instead of a .c extention, and several things will be adjusted to
+a .cc instead of a .c extension, and several things will be adjusted to
make it all work for a C++ compiler. One thing that will be missing is an
alias to the new method, as that clashes with C++, so instead you'll have to
use the full name of the method inside your code. Also note that gob does
not use any C++ features, this option will just make the generated code
compile with a C++ compiler.
-.SH BUGS
+.SH IDENTIFIER CONFLICTS
+.PP
+Gob will need to define some local varibles and functions in the generated
+files, so you need to take some precaution not to conflict with these. The
+general rule of thumb is that all of these start with three underscores. There
+is one, "parent_class" which doesn't because it's intended for use in your
+code. For virtuals or signals, you cannot use the identifier __parent__
+which is used for the parent of the object. You should actually never access
+__parent__ either as it not guaranteed that it will stay named this way.
+Data members cannot be named __parent__ nor _priv. For methods, you cannot
+use the identifiers "init" or "class_init" unless you mean the constructor
+methods. You shouldn't generally use 3 underscores even in override method
+argument lists and virtual and signal method names as it might confuse the
+PARENT_HANDLER macro. In fact avoiding all names with three underscores is
+the best policy when working with gob.
+
+.SH DEALING WITH CIRCULAR HEADERS
+.PP
+Sometimes you may need to use an object of type MyObjectA in the MyObjectB
+class and vice versa. Obviously you can't include headers for both. So you
+need to just declare the typedef in the header of A for B, and the other way
+around as well. The headers generated since v0.92.2 include a protecting
+define before it declares the typedef. This define is the
+__TYPEDEF_<upper case object name>__. So inside my-object-a.h there will be
+this:
+.nf
+
+ #ifndef __TYPEDEF_MY_OBJECT_A__
+ #define __TYPEDEF_MY_OBJECT_A__
+ typedef struct _MyObjectA MyObjectA;
+ #endif
+
+.fi
+Now instead of including my-object-a.h in the header section of
+my-object-b.gob, just copy the above code there and you're set for using
+MyObjectA as a type in the method parameters and public types.
.PP
-The generated header file is included as the first file in the .c file, no
-matter what. This means that you will have to put things that need to be
-included before that, into an %h{ } section.
+Another way to get out of this problem is if you can use those types only
+in the private members, in which case they won't be in the generated public
+header.
+
+.SH BUGS
.PP
Also the lexer does not actually parse the C code, so I'm sure that some corner
cases or maybe even some not so corner cases of C syntax might confuse gob
probably never will. In the future, I might add #if 0 as a comment but
that's about as far as I can really take it and even that is problematic.
Basically, if you use gob, just don't use the C preprocessor too extensively.
+.PP
+Comments will not get through to the generated files unless inside C code.
+This makes using something like gtk-doc harder. However I'm planning to
+fix this somehow.
.SH AUTHOR
.PP