Style Guide

We mostly use the GTK style guide by default. Some exceptions are listed below.

We also target the same toolchain requirements as glib.

General Style hints

  • Overally, we prefer code legibility over brevity or cleverness.

  • Declare variables at the top of the scope, in order they’re used. Mid-function declarations are discouraged.

  • Always use g_autofree and g_autoptr where possible. Do one per line, and make sure they’re initialized to NULL. Asan will complain if they aren’t.

    g_autofree gchar *str = NULL; // This is fine
    g_autofree gchar *str2; // Not initialized to NULL. This is wrong
    
  • Include the minimum number of header files, and list them in alphabetical order.

  • Use spaces instead of tabs. Run this command to check for any occurances of tabs:

    $ grep -r $'\t'
    
  • Use C-style comments for explanitary notes. /* . . . */ instead of C++-style //. The latter are reserved for transient issues.

    • Example: If you have a debugging print-statement that’s often used, feel free to use //. Ex:

        //puzzle_set_model_print (self);
      
    • Example 2: For things that are broken and need to be fixed, we sometimes temporarily will use // as well.

  • We follow the GTK brace convention with if statements, though are a bit more liberal in using braces:

    if (condition)
      do_one_thing ();
    
    if (condition)
      do_one_thing ();
    else
      do_another_thing ();
    
    if (condition)
      {
        do_one_thing ();
        do_another_thing ();
      }
    else
      {
        // Different than GTK convention
        do_a_third_thing ();
      }
    

    That last example is a little different than the GTK style-guide, which might omit the last braces.

FIXME messages

If you’re going to leave a FIXME in the code, please put the domain in parens. That make it easy to grep for all common areas that may need fixing. As an example:

/* FIXME(css): This color is hardcoded instead of css based. See bug #xxx */

We don’t use TODO or have a well maintained TODO.md file. Please file bugs for all other issues.

Common FIXME domains:

  • error: an unhandled error, that probably needs a better message to the user than a g_warning.

  • refactor: clean up an egregiously messy area of code

  • optimization: a chunk of code is unnecessarily slow/big

  • css: Something that should be moved to be a CSS setting

  • gtk/adwaita/libfoo: Work around for an issue in a dependency. Often includes the version number it was fixed or introduced.

  • magichars: A hardcoded constant in the code, that should be centralized or made configurable

  • mystery: Something we don’t understand in the code and couldn’t figure out.

File order

Within a file, we use the following section order. Keep two newlines between each section, and one newline within each section:

  • License

  • Includes

  • Local #defines and enums. Global tables

  • Object properties and signals

  • Object structs

  • Local headers

  • G_DEFINE_TYPE()

  • Object methods, with small helper functions immediately above the caller

  • Local methods, in order they’re called

  • Public methods

  • Global helper functions

Note, this is mostly aspirational, and has settled over time. Very few files follow this to the letter. We fix them as we see them.

Trailing whitespace

We kill all whitespace after any line. To check if the changes in your current branch have any trailing whitespace, run this command:

$ git diff --check master

If your branch isn’t based on master, then replace master with the actual base branch or commit.

To check for all trailing whitespace in the codebase (not just those from your current branch), run this command:

# Do a diff check against the first ever commit,
# and exclude any dirs that we expect to contain trailing whitespace.

# NOTE: You must run this command in the root crosswords directory,
# in order for the exclusions to work.

$ git diff --check 460554e5 -- ':(exclude)word-lists/' ':(exclude)puzzle-sets/'

Please include a trailing newline at the end of the file.