X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=README.Coding;h=3d4c5a59e5d191bbe545ec116b938dee5710b257;hp=956a733a4ce77e7d4b7dd4ceec0dd6449bc3a323;hb=9623c920ab142a3d6dafaaad4086edab9eae63f5;hpb=be300b0588729c3c87f765e2737ebaccc0af02ff diff --git a/README.Coding b/README.Coding index 956a733a4ce..3d4c5a59e5d 100644 --- a/README.Coding +++ b/README.Coding @@ -16,18 +16,15 @@ style should never outweigh coding itself and so the guidelines described here are hopefully easy enough to follow as they are very common and supported by tools and editors. -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 basic style for C code 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. - -We try to stay compatible with Python 2.4, so please don't rely on any -features that were introduced later, such as the "with" statement. +http://www.python.org/pep/pep8. New Python code should be compatible with +Python 2.6, 2.7, and Python 3.4 onwards. This means using Python 3 syntax +with the appropriate 'from __future__' imports. But to save you the trouble of reading the Linux kernel style guide, here are the highlights. @@ -93,6 +90,17 @@ displaying trailing whitespace: set textwidth=80 autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/' +clang-format +------------ +BasedOnStyle: LLVM +IndentWidth: 8 +UseTab: true +BreakBeforeBraces: Linux +AllowShortIfStatementsOnASingleLine: false +IndentCaseLabels: false +BinPackParameters: false +BinPackArguments: false + ========================= FAQ & Statement Reference @@ -192,7 +200,13 @@ characters or less with whitespace. For example, 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 calls, declarations, and +definitions. In function calls, 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 @@ -283,8 +297,8 @@ Good Examples: 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; } @@ -293,7 +307,7 @@ Good Examples: print("Allocated %d elements.\n", y); done: - if (z) { + if (z != NULL) { free(z); } @@ -301,25 +315,6 @@ Good Examples: } -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 -------------------- @@ -334,6 +329,17 @@ lib/replace/, new code should adhere to the following conventions: * 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 -------- @@ -342,6 +348,39 @@ Samba tries to avoid "typedef struct { .. } x_t;" so we do always try to use "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 ---------------------------- @@ -351,7 +390,8 @@ it's also easier to use the "step" command within gdb. Good Example: - char *name; + char *name = NULL; + int ret; name = get_some_name(); if (name == NULL) { @@ -367,6 +407,33 @@ Bad Example: 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 ---------------------------- @@ -377,3 +444,72 @@ 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. + + +Error and out logic +------------------- + +Don't do this: + + frame = talloc_stackframe(); + + if (ret == LDB_SUCCESS) { + if (result->count == 0) { + ret = LDB_ERR_NO_SUCH_OBJECT; + } else { + struct ldb_message *match = + get_best_match(dn, result); + if (match == NULL) { + TALLOC_FREE(frame); + return LDB_ERR_OPERATIONS_ERROR; + } + *msg = talloc_move(mem_ctx, &match); + } + } + + TALLOC_FREE(frame); + return ret; + +It should be: + + frame = talloc_stackframe(); + + if (ret != LDB_SUCCESS) { + TALLOC_FREE(frame); + return ret; + } + + if (result->count == 0) { + TALLOC_FREE(frame); + return LDB_ERR_NO_SUCH_OBJECT; + } + + match = get_best_match(dn, result); + if (match == NULL) { + TALLOC_FREE(frame); + return LDB_ERR_OPERATIONS_ERROR; + } + + *msg = talloc_move(mem_ctx, &match); + TALLOC_FREE(frame); + return LDB_SUCCESS; + + +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.