X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/a611f21fab136f64bbf979bd62b2fc6ecb62933c..3379dcdfd0872947d761053c61d773add94d38c2:/doc/gob.1.in diff --git a/doc/gob.1.in b/doc/gob.1.in index 4268580..a2724c6 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 +[ option ] ... +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,37 @@ 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 +.TP +.B -n +.TP +.B --no-write +Do not write any output files, just check syntax of the input file. .SH TYPENAMES .PP @@ -58,27 +90,57 @@ 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. You may wish to include code or +comments in all the files, which you can do by putting them into the 'all' +(or 'a') section. Similarly, code you wish to appear at the top of all +files go in the 'alltop' (or 'at') section. For example: .nf + %alltop{ + /* this will be on top of all output files */ + %} + + %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); %} + %a{ + /* will be included in all files */ + %} + %{ /* will be included in the C file */ void somefunc(int i) @@ -89,6 +151,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,30 +188,128 @@ 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 -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. +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 third type is an argument type. It is a named datamember 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 -define ARG to which you assign the data or get the data. You can also use -the identifier "self" as pointer to the object instance. The type is -defined as one of the gtk type enums, but without the GTK_TYPE_ prefix. -For example: +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 +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 +Automatic Initialization (0.93.0 and higher only): +.PP +You can automatically initialize the public private and protected data members +without having to add an init method. The advantage here is that +initialization is kept close to the definition of the data member and thus +it's easier to check. To do this, just add a '=' followed by a number or +a token. It is also possible to include arbitrary C code for more elaborate +initializations by putting it all in curly braces. Note that the curly braces +will not be printed into the output, but since gob does not C parsing it needs +them to figure out where the C code ends. The code will be inserted into the +init method, above the user defined body. So for example the following +will initialize an integer to -1 and a string with a newly allocated string +of "hello". +.nf + + public int foo = -1; + private char *bar = {g_strdup("hello")}; + +.fi +.PP +Automatic Destruction (0.93.0 and higher only): +.PP +Most data stored as pointers needs to have a function called when the object +is destroyed, to either free it or give up a reference. Gob will let you +define a function to be called on the data the object is destroyed. This is +achieved by putting 'destroywith' followed by a function name after the +variable definition. It is only called if the data you defined this on +is not NULL, so you cans specify functions which do not handle NULL. It +is very much like the GDestroyNotify function used in GTK+ and glib in many +places. Unlike many other places, gob will not enforce any kind of type +safety here so be a little bit more careful. Any function you give it will +be called as a "void function(void *)". It will in fact be cast into such +a form before called. This is to avoid spurious warnings for gtk calls to +subclass methods. The function needs not be of that form, it just has to +take one argument which is the pointer to the data. You should also not +define this on any non-pointer data as the results may be undefined. +Example: +.nf + + public Gtk:Widget *window = NULL + destroywith gtk_widget_destroy; + public char *foo = {g_strdup("bar")} + destroywith g_free; + +.fi +Note that the function name you give must be a real function and not macro. +Also note that this is always called in the "finalize" method of GtkObject. +.PP +Sometimes you may want to run arbitrary code on destruction. While this can +be perfectly well done in the destroy handler. Depending on the style you +may want to include all destruction/initialization code together with the +definition of the data member. Thus you may want to put arbitrary code which +will then be inserted into the "finalize" method of GtkObject. This can be +done with the "destroy" keyword followed by arbitrary code in curly braces. +Inside this code a macro called VAR will be define which refers to your +variable. So for example destroying a GString can be either done with +a helper routine or the following code: +.nf + + public GString *string = {g_string_new(NULL)} + destroy { + if(VAR) g_string_free(VAR, TRUE); + }; + +.fi +The thing to remember with these is that there are many ways to do this +and you'd better be consistent in your code in how you use the above things. +Also defining a helper routine that will do the destruction will be a nicer +thing to do if that's a possibility. The "destroy" keyword with code does +take up more space in the file and it may become more cluttered. +.PP +GTK+ Arguments: +.PP +The fourth type of a data member 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 define +ARG to which you assign the data or get the data. You can also use the +identifier "self" as pointer to the object instance. The type is defined as +one of the gtk type enums, but without the GTK_TYPE_ prefix. For example: .nf public int height; @@ -140,8 +317,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 @@ -150,20 +327,139 @@ without the GTK_ARG_ prefix. For example: 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 +Sometimes it can become tiresome to type in the set and get handlers if +they are trivial. So gob since version 0.93.0 provides automatic argument +linking to data members. There are three different cases it handles, direct +link (keyword 'link'), string linking (keyword 'stringlink') and object +linking (keyword 'objectlink'). You just place the keyword after the argument +name instead of the get/set handlers. It will link to a data member of the +same name that was defined earlier in the input file. Best is to see examples: +.nf + + public int foo; + argument INT foo link; + +.fi +is just like +.nf + + public int foo; + argument INT (type int) foo + get { ARG = self->foo; } + set { self->foo = ARG; }; + +.fi +Similiarly, +.nf + + private char * foo; + argument POINTER foo stringlink; + +.fi +is just like +.nf + + private char * foo; + argument POINTER (type char *) foo + get { + ARG = self->_priv->foo; + } set { + g_free(self->_priv->foo); + self->_priv->foo = g_strdup(ARG); + } + +.fi +And for the objectlink we would have: +.nf + + public Gtk:Object * foo; + argument POINTER foo objectlink; + +.fi +is just like +.nf + + protected Gtk:Object * foo; + argument POINTER (type Gtk:Object *) foo + get { + ARG = self->foo; + } set { + if(self->foo) + gtk_object_unref(self->foo); + self->foo = ARG; + if(self->foo) + gtk_object_ref(self->foo); + } + +.fi +.PP +As you see it will handle NULLs correctly (for the string, g_free and g_strdup +handle NULLs). And it will also handle private, protected and public members. +Also you should notice that when the get is used, only a pointer is always +returned for both objectlink and strinklink. So you should treat the returned +value with care and never free it (and notice that it will only be around +until you set the argument to something else or destroy the object). .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: +Function 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 +496,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 +504,55 @@ 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 +Default return: +.PP +Some signal and virtual methods have a return type. But what happens if +there is no default handler and no one connects to a signal. GOB will +normally have the wrappers return whatever you specify with onerror or '0' +if you haven't specified anything. But since 0.93.2 you can specify a default +return value with the keyword 'defreturn'. It's use is identical to the +use of onerror, and you can in fact use both at the same time. Example +.nf + + virtual int get_some_int(self) onerror -1 defreturn 10 ; + +.fi +That is an empty virtual method (in C++ terms a pure virtual). If you never +specify any handler for it in the derived children it will just return 10. +.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(self) { + /* initialize the object here */ + self->a = 9; + self->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 +562,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,12 +598,18 @@ 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". .PP +You can also add additional flags. You do this just like with the argument +flags, although this is probably very rare. These are the GTK_RUN_* flags, +and you can add them without the GTK_RUN_ prefix into a parenthesis, just +after the "signal" keyword. By default all public signals are GTK_RUN_ACTION. +.PP Override methods: .PP If you need to override some method (a signal or a virtual method @@ -276,7 +628,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 +662,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 +670,140 @@ will fetch a new object, so a fairly standard new method would look like: } .fi +.PP +Casts: +.PP +There are some standard casts defined for you. Instead of using the full +macros inside the .c file, you can use SELF, IS_SELF and SELF_CLASS. Using +these makes it easier to for example change classnames around. There is +however no self type, so if you're declaring a pointer to your object, you +still have to use the full type. + +.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. +.PP +There are a couple of defines which you shouldn't be redefining in the code +or other headers. These are SELF, IS_SELF, SELF_CLASS, ARG, VAR, +PARENT_HANDLER, GET_NEW, GOB_VERSION_MAJOR, GOB_VERSION_MINOR and +GOB_VERSION_PATCHLEVEL. + +.SH USING GTK-DOC STYLE INLINE DOCUMENTATION +.PP +If you want to use gtk-doc style inline documentation for your objects, you +can do one of two things. First, you could include the inline documentation +comments in your %{ %} section which will then be put verbatim into the +output source file. This is the way you should use for functions you define +outside of the class. +.PP +For class methods, you should use a gtk+ style comment, however it can be +indented any number of tabs or spaces and you can use the short method name +without the type prefix. Gob will automatically try to extract these and +translate to full names and put them in the output source file. An example +would be: +.fi + + class Gtk:Button:Example from Gtk:Button { + /** + * new: + * + * Makes a new #GtkButtonExample widget + * + * Returns: a new widget + **/ + public + GtkWidget * + new(void) + { + return GTK_WIDGET(GET_NEW); + } + } + +.fi +If the function you are documenting is a signal or a virtual then it will +be documentating the wrapper that starts that virtual function or emits +that signal. + +.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 +840,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