X-Git-Url: http://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/a611f21fab136f64bbf979bd62b2fc6ecb62933c..e10d6e307623d0952f6e1f5d9fee8720ddab4808:/doc/gob.1.in diff --git a/doc/gob.1.in b/doc/gob.1.in index 4268580..40916fd 100644 --- a/doc/gob.1.in +++ b/doc/gob.1.in @@ -10,8 +10,9 @@ 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 @@ -24,12 +25,17 @@ is in spirit similar to things like lex or yacc. .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. @@ -37,11 +43,32 @@ 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-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 @@ -58,22 +85,41 @@ types. .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-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); @@ -89,6 +135,23 @@ For example: .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-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: @@ -109,23 +172,49 @@ For example: .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-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 @@ -140,8 +229,8 @@ For example: .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 @@ -149,21 +238,67 @@ without the GTK_ARG_ prefix. For example: 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 _ARG_(x) and +_GET_ARG_(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 )' +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 @@ -200,7 +335,7 @@ default is 0, casted to the type of the method. If you need to return 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 { @@ -208,6 +343,39 @@ output, they just delimit the string. For example } .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 @@ -217,8 +385,9 @@ so that one can override the method in derived methods. They can be empty 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 @@ -252,8 +421,9 @@ or .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". @@ -276,7 +446,11 @@ class, you can use the PARENT_HANDLER macro with your arguments. Example: /* 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 @@ -306,7 +480,7 @@ this method, you can use the GET_NEW macro that is defined for you and that 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); @@ -314,23 +488,92 @@ will fetch a new object, so a fairly standard new method would look like: } .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___. 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 @@ -367,6 +610,10 @@ There is no real good way we can handle this without parsing C code, so we 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