summaryrefslogtreecommitdiff
path: root/CODING_STYLE.md
blob: db4e44c0da7e62a15c5c519938c0ec1c56e99646 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
Formatting
==========

The Pango formatting style is basically the GNU style of formatting
(see http://www.gnu.org/prep/standards.html), with a few additions.
In brief overview:

 - Two character indents are used; braces go on a separate line, and 
   get a separate indentation level, so the total indent for an
   enclosed block is 4 characters.


    ```c
    if (x < foo (y, z))
      haha = bar[4] + 5;
    else
      {
        while (z)
          {
            haha += foo (z, z);
            z--;
          }
        return abc (haha);
      }
    ```

 - Spaces should be present between function name and argument block,
   and after commas.

         foo (z, z)

 - In pointer types, the '*' is grouped with the variable name,
   not with the base type. 

        int *a;

    Not:

        int* a;

   In cases where there is no variable name, for instance, return
   values, there should be a single space between the base type 
   and the '*'.

 - function and variable names are lower_case_with_underscores
   type names are StudlyCaps, macro names are UPPER_CASE_WITH_UNDERSCORES


Standard types
==============

Nowadays, we prefer standard C types over their 'g' typedefs
in many cases:

- int instead of gint
- float instead of gfloat
- double instead of gdouble

Unfortunately, bool is not compatible with gboolean, so we have
to keep using gboolean. The following 'g' types are still used:

- gint64
- gsize
- gssize

The jury is still out on guint vs unsigned int.


Documentation comments
======================

All public API functions should have inline documentation headers
in the gi-docgen style. For instance:

```c
/**
 * pango_layout_get_line:
 * @layout: a `PangoLayout`
 * @line: the index of a line, which must be between 0 and
 *   `pango_layout_get_line_count(layout) - 1`, inclusive.
 *
 * Retrieves a particular line from a `PangoLayout` (or @layout.)
 *
 * Return value: the requested `PangoLine`, or `NULL`
 *   if the index is out of range. This layout line can
 *   be ref'ed and retained, but will become invalid
 *   if changes are made to the `PangoLayout`.
 *
 * Since: 1.6
 */
PangoLine *
pango_layout_get_line (PangoLayout *layout,
                       int          line)
[...]
```

The most noticable difference between old gtk-doc style doc
comments and gi-docgen is linking. gi-docgen can only link
to APIs that have gi-docgen generated docs. To make
cross-project links work, you need to

- Add the gir to the gir dependencies
- Add the prefix to docs/urlmap.js

With gi-docgen, links look like this:

```c
[method@Pango.Context.set_matrix]
```

and require some knowledge of how the linked-to APIs are
represented in gobject-introspection.

Choosing Function Names
=======================

- Don't abbreviate in unexpected ways:

  ```c
  pango_layout_get_line_count ();
  ```

  Not:

  ```c
  pango_layout_ln_cnt ();
  ```

- Functions that retrieve a value in a side-effect free fashion, should
  include "get" in the name.

  ```c
  int pango_layout_get_line_count (PangoLayout *layout);
  ```

  Not:

  ```c
  pango_layout_line_count ();
  ```

  For booleans, "is" can be instead of "get".

- Functions that set a single parameter in a side-effect free fashion
  should include "set" in the name, for instance:

  ```c
  void pango_layout_set_width (PangoLayout    *layout,
                               int             width);
  ```

Other comments
==============

- Avoid unsigned values for all but flags fields. This is because
  the way C handles unsigned values generates bugs like crazy:

  If width is unsigned and 10, then:

  ```c
  int new_width = MAX (width - 15, 1);
  ```

  produces 4294967291, not 1.