f115094d04c59983d8b08fe31545d09799557879
[asterisk/asterisk.git] / doc / CODING-GUIDELINES
1 Asterisk Patch/Coding Guidelines
2
3 To be accepted into the codebase, all non-trivial changes must be
4 disclaimed to Digium or placed in the public domain. For more information
5 see http://bugs.digium.com
6
7 Patches should be in the form of a unified (-u) diff.
8
9 All code, filenames, function names and comments must be in ENGLISH.
10
11 Do not declare variables mid-function (e.g. like GNU lets you) since it is
12 harder to read and not portable to GCC 2.95 and others.
13
14 Don't annotate your changes with comments like "/* JMG 4/20/04 */";
15 Comments should explain what the code does, not when something was changed
16 or who changed it.
17
18 Don't make unnecessary whitespace changes throughout the code.
19
20 Don't use C++ type (//) comments.
21
22 Try to match the existing formatting of the file you are working on.
23
24 Functions and variables that are not intended to be global must be
25 declared static.
26
27 Roughly, Asterisk coding guidelines are generally equivalent to the 
28 following:
29
30 # indent -i4 -ts4 -br -brs -cdw -cli0 -ce -nbfda -npcs -npsl foo.c
31
32 Function calls and arguments should be spaced in a consistent way across
33 the codebase.
34 GOOD: foo(arg1, arg2);
35 GOOD: foo(arg1,arg2);   /* Acceptable but not preferred */
36 BAD: foo (arg1, arg2);
37 BAD: foo( arg1, arg2 );
38 BAD: foo(arg1, arg2,arg3);
39
40 Following are examples of how code should be formatted.
41
42 Functions:
43 int foo(int a, char *s)
44 {
45         return 0;
46 }
47
48 If statements:
49 if (foo) {
50         bar();
51 } else {
52         blah();
53 }
54
55 Case statements:
56 switch (foo) {
57 case BAR:
58         blah();
59         break;
60 case OTHER:
61         other();
62         break;
63 }
64
65 No nested statements without braces, e.g. no:
66
67 for (x=0;x<5;x++)
68         if (foo) 
69                 if (bar)
70                         baz();
71
72 instead do:
73 for (x=0;x<5;x++) {
74         if (foo) {
75                 if (bar)
76                         baz();
77         }
78 }
79
80
81 Make sure you never use an uninitialized variable.  The compiler will 
82 usually warn you if you do so.
83
84 Name global variables (or local variables when you have a lot of them or
85 are in a long function) something that will make sense to aliens who
86 find your code in 100 years.  All variable names should be in lower 
87 case.
88
89 Make some indication in the name of global variables which represent
90 options that they are in fact intended to be global.
91  e.g.: static char global_something[80]
92
93 When making applications, always ast_strdupa(data) to a local pointer if
94 you intend to parse it.
95  if(data)
96   mydata = ast_strdupa(data);
97
98 Always derefrence or localize pointers to things that are not yours like
99 channel members in a channel that is not associated with the current 
100 thread and for which you do not have a lock.
101  channame = ast_strdupa(otherchan->name);
102
103 If you do the same or a similar operation more than 1 time, make it a
104 function or macro.
105
106 Make sure you are not duplicating any functionality already found in an
107 API call somewhere.  If you are duplicating functionality found in 
108 another static function, consider the value of creating a new API call 
109 which can be shared.
110
111 When you achieve your desired functionalty, make another few refactor
112 passes over the code to optimize it.
113
114 Before submitting a patch, *read* the actual patch file to be sure that 
115 all the changes you expect to be there are, and that there are no 
116 surprising changes you did not expect.
117
118 If you are asked to make changes to your patch, there is a good chance
119 the changes will introduce bugs, check it even more at this stage.
120
121 Avoid needless malloc(),strdup() calls.  If you only need the value in
122 the scope of your function try ast_strdupa() or declare struts static
123 and pass them as a pointer with &.
124
125 If you are going to reuse a computable value, save it in a variable
126 instead of recomputing it over and over.  This can prevent you from 
127 making a mistake in subsequent computations, make it easier to correct
128 if the formula has an error and may or may not help optimization but 
129 will at least help readability.
130
131 Just an example, so don't over analyze it, that'd be a shame:
132
133
134 const char *prefix = "pre";     
135 const char *postfix = "post";
136 char *newname = NULL;
137 char *name = "data";
138
139 if (name && (newname = (char *) alloca(strlen(name) + strlen(prefix) + strlen(postfix) + 3)))
140         snprintf(newname, strlen(name) + strlen(prefix) + strlen(postfix) + 3, "%s/%s/%s", prefix, name, postfix);
141
142 vs
143
144 const char *prefix = "pre";
145 const char *postfix = "post";
146 char *newname = NULL;
147 char *name = "data";
148 int len = 0;
149
150 if (name && (len = strlen(name) + strlen(prefix) + strlen(postfix) + 3) && (newname = (char *) alloca(len)))
151         snprintf(newname, len, "%s/%s/%s", prefix, name, postfix);
152
153
154 Use const on pointers which your function will not be modifying, as this 
155 allows the compiler to make certain optimizations.
156
157 == CLI Commands ==
158
159 New CLI commands should be named using the module's name, followed by a verb
160 and then any parameters that the command needs. For example:
161
162 *CLI> iax2 show peer <peername>
163
164 not
165
166 *CLI> show iax2 peer <peername>