described here are hopefully easy enough to follow as they are very
common and supported by tools and editors.
-The basic style, also mentioned in prog_guide4.txt, is the Linux kernel
+The basic style for C code, also mentioned in prog_guide4.txt, is the Linux kernel
coding style (See Documentation/CodingStyle in the kernel source tree). This
closely matches what most Samba developers use already anyways, with a few
exceptions as mentioned below.
+The coding style for Python code is documented in PEP8,
+http://www.python.org/pep/pep8 (with spaces).
+If you have ever worked on another free software Python project, you are
+probably already familiar with it.
+
But to save you the trouble of reading the Linux kernel style guide, here
are the highlights.
The previous example is intended to illustrate alignment of function
parameters across lines and not as encourage for gratuitous line
splitting. Never split a line before columns 70 - 79 unless you
-have a really good reason. Be smart about formatting.
+have a really good reason. Be smart about formatting.
+
+One exception to the previous rule is function declarations and
+definitions. In function declarations and definitions, either the
+declaration is a one-liner, or each parameter is listed on its own
+line. The rationale is that if there are many parameters, each one
+should be on its own line to make tracking interface changes easier.
If, switch, & Code blocks
int ret = 0;
if (y < 10) {
- z = malloc(sizeof(int)*y);
- if (!z) {
+ z = malloc(sizeof(int) * y);
+ if (z == NULL) {
ret = 1;
goto done;
}
print("Allocated %d elements.\n", y);
done:
- if (z) {
+ if (z != NULL) {
free(z);
}
}
-Checking Pointer Values
------------------------
-
-When invoking functions that return pointer values, either of the following
-are acceptable. Use your best judgement and choose the more readable option.
-Remember that many other persons will review it:
-
- if ((x = malloc(sizeof(short)*10)) == NULL ) {
- fprintf(stderr, "Unable to alloc memory!\n");
- }
-
-or:
-
- x = malloc(sizeof(short)*10);
- if (!x) {
- fprintf(stderr, "Unable to alloc memory!\n");
- }
-
-
Primitive Data Types
--------------------
* Boolean values are "true" and "false" (not True or False)
* Exact width integers are of type [u]int[8|16|32|64]_t
+Most of the time a good name for a boolean variable is 'ok'. Here is an
+example we often use:
+
+ bool ok;
+
+ ok = foo();
+ if (!ok) {
+ /* do something */
+ }
+
+It makes the code more readable and is easy to debug.
Typedefs
--------
"struct x { .. };". We know there are still such typedefs in the code,
but for new code, please don't do that anymore.
+Initialize pointers
+-------------------
+
+All pointer variables MUST be initialized to NULL. History has
+demonstrated that uninitialized pointer variables have lead to various
+bugs and security issues.
+
+Pointers MUST be initialized even if the assignment directly follows
+the declaration, like pointer2 in the example below, because the
+instructions sequence may change over time.
+
+Good Example:
+
+ char *pointer1 = NULL;
+ char *pointer2 = NULL;
+
+ pointer2 = some_func2();
+
+ ...
+
+ pointer1 = some_func1();
+
+Bad Example:
+
+ char *pointer1;
+ char *pointer2;
+
+ pointer2 = some_func2();
+
+ ...
+
+ pointer1 = some_func1();
+
Make use of helper variables
----------------------------
Good Example:
- char *name;
+ char *name = NULL;
+ int ret;
name = get_some_name();
if (name == NULL) {
ret = some_function_my_name(get_some_name());
...
+Please try to avoid passing function return values to if- or
+while-conditions. The reason for this is better handling of code under a
+debugger.
+
+Good example:
+
+ x = malloc(sizeof(short)*10);
+ if (x == NULL) {
+ fprintf(stderr, "Unable to alloc memory!\n");
+ }
+
+Bad example:
+
+ if ((x = malloc(sizeof(short)*10)) == NULL ) {
+ fprintf(stderr, "Unable to alloc memory!\n");
+ }
+
+There are exceptions to this rule. One example is walking a data structure in
+an iterator style:
+
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ ... do something with opt ...
+ }
+
+But in general, please try to avoid this pattern.
+
+
+Control-Flow changing macros
+----------------------------
+
+Macros like NT_STATUS_NOT_OK_RETURN that change control flow
+(return/goto/etc) from within the macro are considered bad, because
+they look like function calls that never change control flow. Please
+do not use them in new code.
+
+The only exception is the test code that depends repeated use of calls
+like CHECK_STATUS, CHECK_VAL and others.
+
+
+DEBUG statements
+----------------
+
+Use these following macros instead of DEBUG:
+
+DBG_ERR log level 0 error conditions
+DBG_WARNING log level 1 warning conditions
+DBG_NOTICE log level 3 normal, but significant, condition
+DBG_INFO log level 5 informational message
+DBG_DEBUG log level 10 debug-level message
+
+Example usage:
+
+DBG_ERR("Memory allocation failed\n");
+DBG_DEBUG("Received %d bytes\n", count);
+
+The messages from these macros are automatically prefixed with the
+function name.