summaryrefslogtreecommitdiff
path: root/HACKING
blob: cc4983f64cb7027e9e755203808a55f2f9db49d5 (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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
Pacman - Contributing
=====================

This file is meant to give you a brief overview of coding style and other
concerns when hacking on pacman. If you are interested in contributing, please
read link:submitting-patches.html[submitting-patches] and
link:translation-help.html[translation-help] as well.

Coding Style
------------

1.  All code should be indented with tabs. (Ignore the use of only spaces in
    this file) By default, source files contain the following Vim modeline:
+
[source,C]
-------------------------------------------
/* vim: set noet: */
-------------------------------------------

2.  When opening new blocks such as 'while', 'if', or 'for', leave the opening
    brace on the same line as the beginning of the codeblock. The closing brace
    gets its own line (the only exception being 'else'). Do not use extra
    spaces around the parentheses of the block. ALWAYS use opening and closing
    braces, even if it's just a one-line block. This reduces future error when
    blocks are expanded beyond one line.
+
[source,C]
-------------------------------------------
for(lp = list; lp; lp = lp->next) {
  newlist = _alpm_list_add(newlist, strdup(lp->data));
}

while(it) {
  ptr = it->next;
  if(fn) {
    fn(it->data);
  } else {
    return 1;
  }
  free(it);
  it = ptr;
}
-------------------------------------------

3.  When declaring a new function, put the opening and closing braces on their
    own line. Also, when declaring a pointer, do not put a space between the
    asterisk and the variable name.
+
[source,C]
-------------------------------------------
alpm_list_t *alpm_list_add(alpm_list_t *list, void *data)
{
  alpm_list_t *ptr, *lp;

  ptr = list;
  if(ptr == NULL) {
  ...
  }
  ...
}
-------------------------------------------

4.  Comments should be ANSI-C89 compliant. That means no `// Comment` style;
    use only `/* Comment */` style.

    /* This is a comment */
       NOT
    // This is a comment

5.  Return statements should *not* be written like function calls.

    return 0;
       NOT
    return(0);

6.  The sizeof() operator should accept a type, not a value. (TODO: in certain
    cases, it may be better- should this be a set guideline? Read "The Practice
    of Programming")

    sizeof(alpm_list_t);
       NOT
    sizeof(*mylist);

7.  When using strcmp() (or any function that returns 0 on success) in a
    conditional statement, use != 0 or == 0 and not the negation (!) operator.
    It reads much cleaner for humans (using a negative to check for success is
    confusing) and the compiler will treat it correctly anyway.

    if(strcmp(a, b) == 0)
       NOT
    if(!strcmp(a, b))

8.  Use spaces around almost all arithmetic, comparison and assignment
    operators and after all ',;:' separators.

        foobar[2 * size + 1] = function(a, 6);
           NOT
        foobar[2*size+1]=function(a,6);

        for(a = 0; a < n && n > 0; a++, n--) {}
           NOT
        for(a=0;a<n&&n>0;a++,n--) {}

9.  Declare all variables at the start of the block.
[source,C]
-------------------------------------------
int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url)
{
  char *newurl, *vdata = NULL;

  newurl = url;
  if(!newurl) {
    return -1;
  }

  ...

  if(vdata) {
    ...
  }

  return 1;
}
-------------------------------------------

    NOT

[source,C]
-------------------------------------------
int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url)
{
  char *newurl = url;

  if(!newurl) {
    return -1;
  }

  char *vdata = NULL;

  if(vdata) {
    ...
  }

  return 1;
}
-------------------------------------------


Other Concerns
--------------

Header Includes
~~~~~~~~~~~~~~~

Currently our #include usage is in messy shape, but this is no reason to
continue down this messy path. When adding an include to a file, follow this
general pattern, including blank lines:

[source,C]
-------------------------------------------
#include <standardheader.h>
#include <another.h>
#include <...>
-------------------------------------------

Follow this with some more headers, depending on whether the file is in libalpm
or pacman proper. For libalpm:

[source,C]
-------------------------------------------
/* libalpm */
#include "yourfile.h"
#include "alpm_list.h"
#include "anythingelse.h"
-------------------------------------------

For pacman:

[source,C]
-------------------------------------------
#include <alpm.h>
#include <alpm_list.h>

/* pacman */
#include "yourfile.h"
#include "anythingelse.h"
-------------------------------------------

Never directly include config.h. This will always be added via Makefiles.

GDB and Valgrind Usage
~~~~~~~~~~~~~~~~~~~~~~

When using GDB or valgrind on pacman, you will want to run it on the actual
binary rather than the shell script wrapper produced by libtool. The actual
binary lives at `src/pacman/.libs/lt-pacman`, and will exist after running
`./src/pacman/pacman` at least once.

For example, to run valgrind:

    ./src/pacman/pacman
    valgrind --leak-check=full -- src/pacman/.libs/lt-pacman -Syu

/////
vim:set syntax=asciidoc noet spell spelllang=en_us:
/////