Coding style

How the source code should look like

Quoting the C coding style guidelines from the GNOME project:

The Single Most Important Rule when writing code is this: check the surrounding code and try to imitate it. As a maintainer it is dismaying to receive a patch that is obviously in a different coding style to the surrounding code. This is disrespectful, like someone tromping into a spotlessly-clean house with muddy shoes. So, whatever this document recommends, if there is already written code and you are patching it, keep its current style consistent even if it is not your favorite style.

So, the best way to learn and get used to the coding style used in this projects is really to read the already existing code, as that will help solve most of the doubts one may have when writing new code. If reading the code is not enough, the following coding style guidelines should help as well.

Basic formatting

Line length

There is no strict requirement on the length of the source code lines, especially since there are very long type and function names in e.g. libqmi or libmbim. It is up to the developer how to split lines if appropriate.

Comments

Code comments are always written between /* and */, and multiline comments will have a * prefix in all lines except for the first one.

{
    /* a very long multiline comment to explain something
     * with a lot of detail; see how all the lines after the
     * first one have the asterisk prefix.
     */

    /* single line comments also in the same way, never with // */
}

Always place a whitespace after `/*` and before `*/`.

Indentation and alignment

The sources use 4 spaces to indent, there should be no tabs or longer indentations. In the same way, the alignment is exclusively done with spaces, never with tabs.

{
    /* indented 4 spaces */

    if (something) {
        /* indented 4 more spaces */
        do_something (variable1,
                      variable2,
                      variable3,
                      variable4);
        /* aligned  --^-- here */
    }
}

Spacing

Both method calls and conditionals (e.g. if, for, while…) should always have a whitespace before the ( character.

{
    /* v-------- whitespace before ( */
    if (something) {
                 /* v-------- whitespace before ( */
        do_something (variable1,
                      variable2,
                      variable3,
                      variable4);
    }
}

There should be no whitespace after ( or before ).

Braces

Each function has its opening brace at the next line on the same indentation level as its header.

The blocks inside a function, however, have their opening braces at the same line as their respective control statements; closing braces remain in a line of their own, unless followed by a keyword else or while.

If the contents of the statement are one single command, the braces may be optionally skipped.

static void
a_nice_function (void)
{                                  /* <--------- open brace of function in next line */
    if (something) {               /* <--------- open brace of statement in same line */
        ...
        do_something ();
    } else if (something_else) {   /* <--------- closing brace followed by else-if */
       ...
       do_something_else ();
    } else                         /* <--------- braces skipped for one-command contents */
       do_something_completely_different ();
}

Variables

Variables are always named in lowercase, and separating words with underscores.

The name of the variable should clearly define the purpose of the variable. Using generic names are only allowed for certain very specific cases, e.g. a short name like i is allowed for loop iterators and such.

Variables are defined always at the beginning of the code block where they’re scoped. If a variable is scoped inside an inner scope, it’s also better to define it inside the inner block itself.

If possible, the names of the variables given in the same block should also be vertically aligned. Depending on the length of the type names in the same variable block, more than one vertically aligned groups may be given.

After the definition of all variables, there should be a whiteline before the first method call.

{
    /* all variables defined together at the beginning of the block */
    GError *inner_error = NULL;
    gint    i;
                                                     /* <---- whiteline here! */
    for (i = 0; i < SOME_MAX; i++) {
        /* inside an inner block, variables that apply to the block;
         * in this case with some variable types that are very long
         * so they're aligned vertically in different groups */
        SomeVeryLongTypeNameWeFindHere        input_message;
        AnotherDifferentVeryLongTypeNameWeGot output_message;
        const gchar *name;
        gint         weight;
                                                     /* <---- whiteline here! */
        ...
        name = do_something (i);
        if (name)
            break;
    }
}

Pointers

When defining variables that are pointers, the asterisk must always go next to the variable name, never next to the type.

This is so that there is no confusion on what types are being declared if e.g. more than one variable is defined in the same line.

{
    /* These are two pointers to guint variables. With the asterisk next to the
     * variable name, it's clear they are both pointers. */
    guint *val1, *val2;

    /* If the asterisk was placed next to the type, it would get confusing.
     * This is a pointer to a guint (val3) and a guint (val4), not two
     * pointers. */
    guint* val3, val4;

    ...
}

Methods

Methods are always named in lowercase, and separating words with underscores.

The name of the method should clearly define the purpose of the method.

If possible, the names of the method arguments given in the method declaration and definitions should also be vertically aligned. Depending on the length of the type names, more than one vertically aligned groups may be given.

When a method is defined, it should provide the return type of the method in a separate line, before the name of the method. When a method is declared, the return type should be given in the same line as the name of the method.

Definition of module private methods

Methods that are going to be used exclusively in the same source file where they are defined (private methods) should be made static, and not declared in any header. The name of this kind of methods doesn’t need to have any explicit prefix.

/* return type and method name in separate lines */
static gboolean
do_something (gint          max,
              gint          min,
              const gchar  *text,
              GError      **error)
{
    /* definition here */
}

Declaration and definition of module public methods

Methods that are meant to be used out of the source file where they are defined (public methods) should have a clear declaration in a header file and the definition inside the source file with the same file name. All the public methods in the same module should have the same string prefix, clearly stating the module they come from.

E.g. in the header file some-module.h:

/* return type and method name in the same line */
gboolean some_module_do_something (const gchar  *text,
                                   GError      **error);

And in source file some-module.c:

/* return type and method name in separate lines */
gboolean
some_module_do_something (const gchar  *text,
                          GError      **error)
{
    /* definition here */
}

Symbols

Symbols are always named in uppercase, and separating words with underscores.

The name of the symbol should clearly define the purpose of the symbol.

Symbols are usually defined at the beginning of the header or source file, with an explanation of what they are for given in a comment.

In the same way as methods, if the symbols are defined in the header file of a module, the name of the symbol should have the common prefix used in the module.

/* Maximum time to wait for the operation to complete, in seconds */
#define SOME_MODULE_MAX_TIMEOUT_SECS 10