lib: Add support to parse MS Catalog files
[samba.git] / README.Coding
index 956a733a4ce77e7d4b7dd4ceec0dd6449bc3a323..65d72d6fb735cc5274903f023833894183b096c3 100644 (file)
@@ -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.
 
 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,
 
 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.
+https://www.python.org/dev/peps/pep-0008/. 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.
 
 But to save you the trouble of reading the Linux kernel style guide, here
 are the highlights.
@@ -93,6 +90,18 @@ displaying trailing whitespace:
   set textwidth=80
   autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
 
   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
+SortIncludes: false
+
 
 =========================
 FAQ & Statement Reference
 
 =========================
 FAQ & Statement Reference
@@ -192,7 +201,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
 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
 
 
 If, switch, & Code blocks
@@ -283,8 +298,8 @@ Good Examples:
                int ret = 0;
 
                if (y < 10) {
                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;
                        }
                                ret = 1;
                                goto done;
                        }
@@ -293,7 +308,7 @@ Good Examples:
                print("Allocated %d elements.\n", y);
 
         done:
                print("Allocated %d elements.\n", y);
 
         done:
-               if (z) {
+               if (z != NULL) {
                        free(z);
                }
 
                        free(z);
                }
 
@@ -301,25 +316,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
 --------------------
 
 Primitive Data Types
 --------------------
 
@@ -334,6 +330,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
 
   * 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
 --------
 
 Typedefs
 --------
@@ -342,6 +349,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.
 
 "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
 ----------------------------
 
 Make use of helper variables
 ----------------------------
 
@@ -351,7 +391,8 @@ it's also easier to use the "step" command within gdb.
 
 Good Example:
 
 
 Good Example:
 
-       char *name;
+       char *name = NULL;
+       int ret;
 
        name = get_some_name();
        if (name == NULL) {
 
        name = get_some_name();
        if (name == NULL) {
@@ -367,6 +408,33 @@ Bad Example:
        ret = some_function_my_name(get_some_name());
        ...
 
        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
 ----------------------------
 
 Control-Flow changing macros
 ----------------------------
 
@@ -377,3 +445,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.
 
 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.