aboutsummaryrefslogtreecommitdiff
blob: c4ec6ca03643c701c8bb04190da6463d2a9ca856 (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
Libvirt contributor guidelines
==============================


Code indentation
================
Libvirt's C source code generally adheres to some basic code-formatting
conventions.  The existing code base is not totally consistent on this
front, but we do prefer that contributed code be formatted similarly.
In short, use spaces-not-TABs for indentation, use 4 spaces for each
indentation level, and other than that, follow the K&R style.

If you use Emacs, add the following to one of one of your start-up files
(e.g., ~/.emacs), to help ensure that you get indentation right:

  ;;; When editing C sources in libvirt, use this style.
  (defun libvirt-c-mode ()
    "C mode with adjusted defaults for use with libvirt."
    (interactive)
    (c-set-style "K&R")
    (setq indent-tabs-mode nil) ; indent using spaces, not TABs
    (setq c-indent-level 4)
    (setq c-basic-offset 4))
  (add-hook 'c-mode-hook
	    '(lambda () (if (string-match "/libvirt" (buffer-file-name))
			    (libvirt-c-mode))))

Code formatting (especially for new code)
=========================================
With new code, we can be even more strict.
Please apply the following function (using GNU indent) to any new code.
Note that this also gives you an idea of the type of spacing we prefer
around operators and keywords:

  indent-libvirt()
  {
    indent -bad -bap -bbb -bli4 -br -ce -brs -cs -i4 -l75 -lc75 \
      -sbi4 -psl -saf -sai -saw -sbi4 -ss -sc -cdw -cli4 -npcs -nbc \
      --no-tabs "$@"
  }

Note that sometimes you'll have to postprocess that output further, by
piping it through "expand -i", since some leading TABs can get through.
Usually they're in macro definitions or strings, and should be converted
anyhow.


Low level memory management
===========================

Use of the malloc/free/realloc/calloc APIs is deprecated in the libvirt
codebase, because they encourage a number of serious coding bugs and do
not enable compile time verification of checks for NULL. Instead of these
routines, use the macros from memory.h

  - eg to allocate  a single object:

      virDomainPtr domain;

      if (VIR_ALLOC(domain) < 0) {
         __virRaiseError(VIR_ERROR_NO_MEMORY)
         return NULL;
      }


  - eg to allocate an array of objects

       virDomainPtr domains;
       int ndomains = 10;

       if (VIR_ALLOC_N(domains, ndomains) < 0) {
         __virRaiseError(VIR_ERROR_NO_MEMORY)
         return NULL;
       }

  - eg to allocate an array of object pointers

       virDomainPtr *domains;
       int ndomains = 10;

       if (VIR_ALLOC_N(domains, ndomains) < 0) {
         __virRaiseError(VIR_ERROR_NO_MEMORY)
         return NULL;
       }

   - eg to re-allocate the array of domains to be longer

       ndomains = 20

       if (VIR_REALLOC_N(domains, ndomains) < 0) {
         __virRaiseError(VIR_ERROR_NO_MEMORY)
         return NULL;
       }

   - eg to free the domain

       VIR_FREE(domain);



String comparisons
==================

Do not use the strcmp, strncmp, etc functions directly. Instead use
one of the following semantically named macros

  - For strict equality:

     STREQ(a,b)
     STRNEQ(a,b)

  - For case sensitive equality:
     STRCASEEQ(a,b)
     STRCASENEQ(a,b)

  - For strict equality of a substring:

     STREQLEN(a,b,n)
     STRNEQLEN(a,b,n)

  - For case sensitive equality of a substring:

     STRCASEEQLEN(a,b,n)
     STRCASENEQLEN(a,b,n)

  - For strict equality of a prefix:

     STRPREFIX(a,b)



Variable length string buffer
=============================

If there is a need for complex string concatenations, avoid using
the usual sequence of malloc/strcpy/strcat/snprintf functions and
make use of the virBuffer API described in buf.h

eg typical usage is as follows:

  char *
  somefunction(...) {
     virBuffer buf = VIR_BUFFER_INITIALIZER;

     ...

     virBufferAddLit(&buf, "<domain>\n");
     virBufferVSprint(&buf, "  <memory>%d</memory>\n", memory);
     ...
     virBufferAddLit(&buf, "</domain>\n");

     ....

     if (virBufferError(&buf)) {
         __virRaiseError(...);
         return NULL;
     }

     return virBufferContentAndReset(&buf);
  }


Include files
=============

There are now quite a large number of include files, both libvirt
internal and external, and system includes.  To manage all this
complexity it's best to stick to the following general plan for all
*.c source files:

  /*
   * Copyright notice
   * ....
   * ....
   * ....
   *
   */

  #include <config.h>             Must come first in every file.

  #include <stdio.h>              Any system includes you need.
  #include <string.h>
  #include <limits.h>

  #if HAVE_NUMACTL                Some system includes aren't supported
  #include <numa.h>               everywhere so need these #if defences.
  #endif

  #include "internal.h"           Include this first, after system includes.

  #include "util.h"               Any libvirt internal header files.
  #include "buf.h"

  static myInternalFunc ()        The actual code.
  {
    ...

Of particular note: *DO NOT* include libvirt/libvirt.h or
libvirt/virterror.h.  It is included by "internal.h" already and there
are some special reasons why you cannot include these files
explicitly.