File: HACKING.html

package info (click to toggle)
redland 1.0.17-1.1
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid, stretch
  • size: 8,780 kB
  • ctags: 4,263
  • sloc: ansic: 37,638; sh: 12,115; perl: 2,590; xml: 807; makefile: 587
file content (403 lines) | stat: -rw-r--r-- 11,388 bytes parent folder | download | duplicates (2)
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
  <title>Redland RDF Application Framework - Hacking Redland librdf</title>
  <style type="text/css">
<!--
pre
{
	margin: 1em 4em 1em 4em;
	background-color: #eee;
	padding: 0.5em;
	border-color: #006;
	border-width: 1px;
	border-style: dotted;
}
-->
  </style>
</head>
<body>
  <h1>Hacking Redland librdf</h1>
  
  <p>2011-08-23</p>
  
  <p><a href="http://www.dajobe.org/">Dave Beckett</a></p>
  
  <h2>Commits</h2>
  
  <p>Should be:</p>
  
  <ul>
  <li>Licensed with the same license as Redland librdf.</li>
  <li>Patches in GNU <code>diff -u</code> unifed context format preferred.</li>
  <li>Include tests if they add new features.</li>
  </ul>
  
  <h2>Code Style</h2>
  
  <p>Do not make large commits that only change code style unless you have
  previously had this agreed or it is in code under major refactoring
  where a diff is not a large concern.  There is always <code>diff -b</code> when
  large code style (whitespace) changes are made.</p>
  
  <h3>Indenting</h3>
  
  <p>2 spaces.  No tabs.</p>
  
  <p>All code must be wrapped to 80 chars as far as is possible.  Function
  definitions or calls should indent the parameters to the left <code>(</code>.</p>
  
  <p>Redland libraries use very long function names following the naming
  convention which can make linebreaking very hard.  In this case,
  indent function parameters on new lines 4 spaces after the function
  name like this:</p>
  
  <pre><code>
  var = function_name_with_very_long_name_that_is_hard_to_wrap_args(
            argument1_with_very_long_name_or_expression,
            argument2,
            ..)
  </code></pre>
  
  <p>Use no space between a keyword followed by braces argument.
  For example, use <code>if(cond)</code> rather than <code>if (cond)</code> (ditto for
  while, do etc.) and
  <code>functionname(...)</code> rather than <code>functionname (...)</code> in
  both definition and calls of functions.</p>
  
  <p>There is nothing wrong with introducing a variable to break up a very
  long function call argument.</p>
  
  <h3>Expressions</h3>
  
  <p>Put spaces around operators in expressions, assignments, tests, conditions</p>
  
  <p>GOOD:</p>
  
  <ul>
  <li><code>a += 2 * x</code></li>
  <li><code>if(a &lt; 2)</code></li>
  </ul>
  
  <p>BAD:</p>
  
  <ul>
  <li><code>a+=2*x</code></li>
  <li><code>if(a&lt;2)</code></li>
  </ul>
  
  <p>When comparing to <code>0</code> or a <code>NULL</code> pointer, use the idiomatic form
  that has no comparison.</p>
  
  <p>GOOD:</p>
  
  <ul>
  <li><code>if(!ptr)</code></li>
  <li><code>if(!index)</code></li>
  </ul>
  
  <p>BAD:</p>
  
  <ul>
  <li><code>if(ptr == NULL)</code></li>
  <li><code>if(index == 0)</code></li>
  <li><code>if(0 == index)</code></li>
  </ul>
  
  <p>When comparing a variable to a constant, the code has currently used
  <code>if(var == constant)</code> rather than the slightly safer, and easier to
  compile check, <code>if(constant == var)</code>.</p>
  
  <h3>Blocks</h3>
  
  <p>In general add {}s around blocks in if else chains when one of the blocks
  has more than 1 line of code.  Try not to mix, but the final case if it
  is one line, can be braceless.</p>
  
  <pre><code>
  if(var == 1) {
    ... multiple lines of code ...
  } else {
    ... multiple lines of code ...
  }
  </code></pre>
  
  <p>or</p>
  
  <pre><code>
  if(var == 1)
    ... one line of code
  else
    ... one line of code
  </code></pre>
  
  <p>or</p>
  
  <pre><code>
  if(var == 1) {
    ... multiple lines of code ...
  } else if(var == 2) {
    ... multiple lines of code and / or more if conditions ...
  } else
    ... one line of code ...
  </code></pre>
  
  <h3>Switches</h3>
  
  <p>If using if else chains on an enumeration, don't do that, use a
  <code>switch()</code> which GCC can use to find missing cases when they get added.</p>
  
  <pre><code>
  switch(enum_var) {
    case ENUM_1:
      ... code ...
      break;
  
    case ENUM_2:
      ... code ...
      break;
  
    case ENUM_DONT_CARE:
    default:
      ... code ...
      break;
  }
  </code></pre>
  
  <p>There should ALWAYS be a <code>default:</code> case.</p>
  
  <h3>Functions</h3>
  
  <p>Declare functions in this format:</p>
  
  <pre><code>
  returntype
  functionname(type1 param1, type2 param2, ...)
  {
    type3 var1;
    type4 var2;
  
    ... first line of code ...
  
    tidy:
      ... cleanup code...
  
    return value;
   }
  </code></pre>
  
  <p>Notes:</p>
  
  <ul>
  <li>Declare one variable per line</li>
  <li>Declare all variables at the top of the function (K&amp;R C style)</li>
  <li>You may declare variables in inner <code>{}</code> blocks.  The
   form <code>if(1) { ... var decls ...; more code }</code> may be used but
   a code rewrite is preferable.</li>
  <li>If a label is used it <em>MUST</em> be used only for cleanup, and going
   forward in the code to the end of the function.</li>
  <li>Multiple <code>return</code> are allowed but for obvious error or result
   returns.  Do not twist the code to enable a single return.</li>
  <li><code>goto</code> may be used for resource cleanup and result return 
   where control flow only goes forward.</li>
  </ul>
  
  <h3>C Pre-Processor (CPP) Macros</h3>
  
  <p>Always define macros for internal constants and name the macros with
  the library prefix followed by a descriptive name in ALL CAPS such as:</p>
  
  <pre><code>
  #define LIBRDF_FOOBAR_BUFFER_SIZE 1234
  </code></pre>
  
  <p>When evaluating macro symbols that may be undefined, always check the
  symbol is defined first.  Like this:</p>
  
  <pre><code>
  #if defined(LIBRDF_DEBUG) &amp;&amp; LIBRDF_DEBUG &gt; 42
     ... do complex debugging stuff ...
  #endif
  </code></pre>
  
  <p>This is not needed for macros that are known to be defined, such as those
  checked by <code>configure</code> e.g.</p>
  
  <pre><code>
  #if RAPTOR_VERSION_DECIMAL &gt; 20100
     ... do stuff that requires a raptor2 version 2.1.0 or newer ...
  #endif
  </code></pre>
  
  <p>since the above would be checked implicitly by <code>configure</code> using
  <code>pkg-config(1)</code> to validate Raptor 2 is present before getting to the
  code that tries to evaluate the value from <code>raptor2.h</code>.</p>
  
  <p>The debug macros that are used for printing out values when debugging
  is enabled do not need protection by <code>#if</code> or <code>#ifdef</code> and should be
  used like this:</p>
  
  <pre><code>
  LIBRDF_DEBUG1("Something wonderful happened\n");
  
  LIBRDF_DEBUG2("Something %s happened\n", happening);
  </code></pre>
  
  <h3>Memory allocation</h3>
  
  <p>Allocating a zeroed out block of memory or a set of objects (calloc)</p>
  
  <pre><code>
  var = LIBRDF_CALLOC(type, count, size)
  </code></pre>
  
  <p>Prefering when <code>count</code> = 1 this form:</p>
  
  <pre><code>
  var = LIBRDF_CALLOC(type, 1, sizeof(*var))
  </code></pre>
  
  <p>Allocating a block of memory:</p>
  
  <pre><code>
  var = LIBRDF_MALLOC(type, size)
  </code></pre>
  
  <p>Freeing memory:    </p>
  
  <pre><code>
  LIBRDF_FREE(type, var)
  </code></pre>
  
  <p>The reasoning here is to make allocs mostly fit into 1 line without
  too much boilerplate and duplication of types.</p>
  
  <p>The macro names vary by library such as <code>RAPTOR_CALLOC</code> and
  <code>RASQAL_CALLOC</code> for Raptor and Rasqal respectively.</p>
  
  <h3>Documentation</h3>
  
  <p>Public functions, types, enumerations and defines must have autodocs -
  the structured comment block before the definition.  This is read by
  <code>gtk-doc(1)</code> to generate reference API documentation.</p>
  
  <p>Format:</p>
  
  <pre><code>
  /**
   * functionname:
   * @param1: Description of first parameter
   * @param2: Description of second parameter (or NULL)
   * ... more params ...
   *
   * Short Description
   *
   * Long Description.
   *
   * Return value: return value
   */
   returntype
   functionname(...)
   {
     ... body ...
   }
  </code></pre>
  
  <p>The <em>Short Description</em> have several commmon forms:</p>
  
  <ul>
  <li>Constructor - creates a FOO object</li>
  <li>Destructor - destroys a FOO object</li>
  <li>Short description of regular function or method.</li>
  <li>INTERNAL - short description</li>
  </ul>
  
  <p>The latter is used for autodocs for internal functions either as
  internal documentation or for APIs that may one day be public.</p>
  
  <p>The <em>(or NULL)</em> phrase is used for pointer parameters that may be
  omitted.  This is usually tested by the function as an assertion.
  In some functions there are more complex conditions on which optional
  parameters are allowed, these are described in the <em>Long Description</em>.</p>
  
  <p>The long description may also include a deprecation statement such as:</p>
  
  <pre><code>
  * @Deprecated: Use new_function() with foo = BAR
  </code></pre>
  
  <p>This must be indented to the left and will be used by the
  <code>gtk-doc(1)</code> document generator to provide a link to the replacement
  function and usage.</p>
  
  <h2>Commit Messages</h2>
  
  <p>The general standard for Redland libraries using GIT is a merge
  of the GIT standards format and GNU ChangeLog</p>
  
  <pre><code>
  First line summaries what commit does - this goes into the GIT short log
  
  (function1, function2): what changed
  
  (function3): Added, deprecating function4()
  
  (function4): Deleted, replaced by function3()
  
  struct foo gains field ...
  
  struct bar loses field ...
  
  enum blah gains new value BLAH_2 which ...
  </code></pre>
  
  <p>Use <code>name()</code> in the description for references to functions.
  Make sure to do (function1, function2) NOT (function1,function2) as
  it makes things easier to format later.</p>
  
  <p>Sometimes it's short enough (good) that it all can be done in the first
  line, pretty much only if it's a small change to a single function.</p>
  
  <p>If the change is trivial or a typo and (this is <em>IMPORTANT</em>) NOT a
  commit to code files, then the commit can start with '#'.  This may
  get filtered out of commit log message notifications and ChangeLog.</p>
  
  <p>e.g.  <code>#spelling</code>  or <code>#ws</code>
  the latter is whitespace changes for some reason</p>
  
  <p>The changes will semi-automatically be added to the ChangeLog files
  following the GNU style, indented and word wrapped, and adding the list
  of files at the start.  So the commit message above ends up looking
  something like:</p>
  
  <pre><code>
  2010-08-23  User Name &lt;user@example.org&gt;
  
          * dir/file1.c, dir2/file2.c: First line summaries what commit
            does - this goes into the GIT short log
  
            (function1, function2): what changed
  
            (function3): Added, deprecating function4()
  
            (function4): Deleted, replaced by function3()
  
            struct foo gains field ...
  
            struct bar loses field ...
  
            enum blah gains new value BLAH_2 which ...
  </code></pre>
  
  <!--
  Local variables:
  mode: markdown
  End:
  -->
<hr />

<p>Copyright (C) 2013 <a href="http://www.dajobe.org/">Dave Beckett</a></p>

</body>
</html>