This coding style is (or should be) used for all the core Telepathy components, notably telepathy-glib, libtelepathy, telepathy-gabble and telepathy-stream-engine.
These are guidelines only; there are always exceptional circumstances. Consistency and readability are usually the most important considerations.
C code using GLib/GObject
Filenames
Don't put a common prefix on all files in a project - we like our tab completion to work (<telepathy-glib/connection.h> is good, <telepathy-glib/tp-connection.h> would be bad)
If you're writing a library where headers will be included like <foo/bar.h>, put the headers (and probably corresponding sources) in a directory called foo (probably top-level).
This way the library and its examples/tests can be compiled with -I$(top_srcdir) -I$(top_builddir) (or possibly -I$(top_srcdir)/src -I$(top_builddir)/src or something) and use #include <foo/bar.h> throughout
- Code generation tools (a la telepathy-glib) typically go in ./tools
- The darcs 'boringfile' preference (the filename used as a .cvsignore equivalent) is typically set to '_boring'
autoconf macros usually go in ./m4. This requires AC_CONFIG_MACRO_DIR([m4]) in configure.ac and ACLOCAL_AMFLAGS = -I m4 in the top-level Makefile.am (use both).
#includes
If you're going to #include "config.h", do that first, in case it defines things like "inline".
Next, #include the header in which this .c file's API is declared. This guarantees that all public headers are self-contained.
Next, #define any libc feature-test macros you need (_GNU_SOURCE etc.) and #include any C/POSIX standard library headers you need, in alphabetical order.
Next, #include any headers you need from non-standard libraries (GLib, Gtk, telepathy-glib, Avahi, ...) in alphabetical order.
Finally, #include any private (non-installed) headers from the library or program you're writing.
For example:
/* Example 1: foo.c * ... insert copyright etc. here ... */ #include "config.h" #include "foo.h" #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112L /* for posix_memalign */ #endif #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <avahi-common/address.h> #include <glib-object.h> #include <telepathy-glib/bar.h> #define DEBUG_FLAG DEBUG_FOO #include "bar.h" #include "debug.h" #include "foobar.h"
(Try to avoid using non-standard functions that need feature test macros - I've just used posix_memalign here for the sake of an example.)
Layout
- Indentation is GNU-style:
/* Example 2 */
while (foo)
{
if (badger != NULL)
bar ();
if (mushroom != NULL)
{
do_stuff ();
}
else
{
do_more_stuff ();
do_yet_more_stuff ();
}
}- Function declarations are in the style:
/* Example 3 */
static void badger_mushroom (Mushroom *self,
const gchar *reason,
gint another_param,
...,
gpointer omg_so_many_params);- but function definitions are in the style:
/* Example 4 */
static void
badger_mushroom (Mushroom *self,
const gchar *reason,
gint another_param,
...,
gpointer omg_so_many_params)
{
...
}(Rationale: that way you can grep for ^function_name and you'll only find the definition, without any clutter caused by declarations).
- Two blank lines between function definitions.
- Function calls have a space after the function name.
Long lines (>79 chars) should be wrapped with a four-space indent, like this:
/* Example 5 */ static void do_some_stuff (Mushroom *self) { do_some_other_stuff (self, 123, 42, TP_TYPE_MUSHROOM, OTHER_STUFF_ADD_BADGERS | OTHER_STUFF_NO_SNAKES, "this example has too many parameters", CARROTS | HANDBAGS | CHEESE, TABLET, BRICK, POTATO, LLAMA); }- Exception: definitions (but not declarations) have exactly one parameter per line, with second and subsequent lines indented to match first line, like Example 4
Naming
Functions allocating memory should end in _new.
Accessor functions named like "tp_foo_get_bar" shouldn't copy bar. If bar is of a type like gchar * or TpIntSet * where const pointers are useful, they should return something like "const gchar *" or "const TpIntSet *".
- Accessor functions named like "tp_foo_dup_bar" should copy bar (or return a new reference if it's refcounted). They don't return const types.
- If "bar" is a GObject you should usually only provide tp_foo_dup_bar, and not tp_foo_get_bar (refcount changes are cheap).
- Some existing code uses tp_foo_borrow_bar for the "borrowed reference" case, to make it explicit that the refcount isn't incremented. (FIXME: should we discourage this in future?)
Build system
List libs and cflags in stack order, with lowest in the stack first (so one can link against highest in the stack somewhere else without picking up everything from the somewhere else). (This guideline was borrowed from gstreamer)
# Example 6 AM_CFLAGS = $(DBUS_CFLAGS) $(GLIB_CFLAGS) $(DBUS_GLIB_CFLAGS) $(TP_GLIB_CFLAGS) something_LDADD = $(DBUS_LIBS) $(GLIB_LIBS) $(DBUS_GLIB_LIBS) $(TP_GLIB_LIBS)
Misc
- Use glib types for preference.
- Casts look like:
Fungus *fungus; Mushroom *mushroom; mushroom = MUSHROOM (fungus); /* or if there's no suitable asserting macro or if the cast is from * a subclass to a superclass, */ mushroom = (Mushroom *) fungus;
- Use gchar * for strings that should be freed with g_free, char * for strings that should be freed with e.g. avahi_free.
- Use the G_GNUC_* function annotations where possible.
- Use GSlice allocation for non-GObjects where possible.
Use g_set_error instead of g_error_new where possible.
- Never use explicit comparisons with TRUE and FALSE for booleans - if have_value is a gboolean, use "if (have_value)" instead of "if (have_value == TRUE)".
- Always use explicit comparisons for non-boolean integers and for pointers - if i is an integer and p is a pointer, use "if (i != 0)" instead of "if (i)", and "if (p != NULL)" instead of "if (p)".
Python
See PEP 8.
Indentation should always be 4 spaces.
C++ code using Qt
telepathy-qt4 is meant to be in the kdelibs coding style.
The same build system, #include and filename guidelines as for C/GLib/GObject (above) apply to C++.
Emacs C Mode
Adding the following to your .emacsrc creates a Telepathy style for you:
(defun telepathy-c-initialization-hook ()
(c-add-style "telepathy"
'("gnu"
(indent-tabs-mode . nil)
(c-offsets-alist
(arglist-intro . 4)
(arglist-cont-nonempty . 4)))))
(add-hook 'c-initialization-hook 'telepathy-c-initialization-hook)You can also set telepathy style as default:
(setq c-default-style "telepathy")
Vim Configuration
Adding the following to your .vimrc should help with adherence to these guidelines:
set cino=>2s,{1s,n-s,^-s
autocmd FileType python setl tw=78 ts=4 sts=4 sw=4 et
autocmd FileType c setl tw=78 ts=2 sts=2 sw=2 et
