mirror of
				https://github.com/Telecominfraproject/OpenNetworkLinux.git
				synced 2025-10-30 17:58:16 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			501 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			501 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
 | |
|                    OpenNetworkLinux C Coding Style
 | |
|                    ===============================
 | |
| 
 | |
| This file describes the coding style used in most C files in this
 | |
| repository. It is based on the Open vSwitch coding style guide.
 | |
| 
 | |
| BASICS
 | |
| 
 | |
|   Limit lines to 79 characters.
 | |
| 
 | |
|   Do not use tabs for indentation.
 | |
| 
 | |
|   Avoid trailing spaces on lines.
 | |
| 
 | |
|   Avoid empty lines at the end of files.
 | |
| 
 | |
|   Use unix newlines (\n).
 | |
| 
 | |
| 
 | |
| NAMING
 | |
| 
 | |
|   Use names that explain the purpose of a function or object.
 | |
| 
 | |
|   Use underscores to separate words in an identifier: multi_word_name. 
 | |
| 
 | |
|   Use lowercase for most names.  Use uppercase for macros, macro
 | |
| parameters, and members of enumerations.
 | |
| 
 | |
|   Give arrays names that are plural.
 | |
| 
 | |
|   Pick a unique name prefix (ending with an underscore) for each
 | |
| module, and apply that prefix to all of that module's externally
 | |
| visible names.  Names of macro parameters, struct and union members,
 | |
| and parameters in function prototypes are not considered externally
 | |
| visible for this purpose. Modules that span multiple files should
 | |
| use this prefix for names shared between the files, even if they are
 | |
| not in a public header file.
 | |
| 
 | |
|   Do not use names that begin with _.  If you need a name for
 | |
| "internal use only", use __ as a suffix instead of a prefix.
 | |
| 
 | |
|   Avoid negative names: "found" is a better name than "not_found".
 | |
| 
 | |
|   In names, a "size" is a count of bytes, a "length" is a count of
 | |
| characters.  A buffer has size, but a string has length.  The length
 | |
| of a string does not include the null terminator, but the size of the
 | |
| buffer that contains the string does.
 | |
| 
 | |
| 
 | |
| COMMENTS
 | |
| 
 | |
|   Comments should be written as full sentences that start with a
 | |
| capital letter and end with a period.  Put a single space between
 | |
| sentences.
 | |
| 
 | |
|   Write block comments as shown below.  You may put the /* and */ on
 | |
| the same line as comment text if you prefer.
 | |
| 
 | |
|     /*
 | |
|      * We redirect stderr to /dev/null because we often want to remove all
 | |
|      * traffic control configuration on a port so its in a known state.  If
 | |
|      * this done when there is no such configuration, tc complains, so we just
 | |
|      * always ignore it.
 | |
|      */
 | |
| 
 | |
|   Each function and each variable declared outside a function, and
 | |
| each struct, union, and typedef declaration should be preceded by a
 | |
| comment.  See FUNCTION DEFINITIONS below for function comment
 | |
| guidelines.
 | |
| 
 | |
|   Each struct and union member should each have an inline comment that
 | |
| explains its meaning.  structs and unions with many members should be
 | |
| additionally divided into logical groups of members by block comments,
 | |
| e.g.:
 | |
| 
 | |
|     /* An event that will wake the following call to poll_block(). */
 | |
|     struct poll_waiter {
 | |
|         /* Set when the waiter is created. */
 | |
|         struct list node;           /* Element in global waiters list. */
 | |
|         int fd;                     /* File descriptor. */
 | |
|         short int events;           /* Events to wait for (POLLIN, POLLOUT). */
 | |
|         poll_fd_func *function;     /* Callback function, if any, or null. */
 | |
|         void *aux;                  /* Argument to callback function. */
 | |
|         struct backtrace *backtrace; /* Event that created waiter, or null. */
 | |
| 
 | |
|         /* Set only when poll_block() is called. */
 | |
|         struct pollfd *pollfd;      /* Pointer to element of the pollfds array
 | |
|                                        (null if added from a callback). */
 | |
|     };
 | |
| 
 | |
|   Use XXX or FIXME comments to mark code that needs work.
 | |
| 
 | |
|   Don't use // comments.
 | |
| 
 | |
|   Don't comment out or #if 0 out code.  Just remove it.  The code that
 | |
| was there will still be in version control history.
 | |
| 
 | |
| 
 | |
| FUNCTIONS
 | |
| 
 | |
|   Put the return type, function name, and the braces that surround the
 | |
| function's code on separate lines, all starting in column 0.
 | |
| 
 | |
|   Before each function definition, write a comment that describes the
 | |
| function's purpose, including each parameter, the return value, and
 | |
| side effects.  References to argument names should be given in
 | |
| single-quotes, e.g. 'arg'.  The comment should not include the
 | |
| function name, nor need it follow any formal structure.  The comment
 | |
| does not need to describe how a function does its work, unless this
 | |
| information is needed to use the function correctly (this is often
 | |
| better done with comments *inside* the function).
 | |
| 
 | |
|   Simple static functions do not need a comment.
 | |
| 
 | |
|   Within a file, non-static functions should come first, in the order
 | |
| that they are declared in the header file, followed by static
 | |
| functions.  A commonly useful way to divide groups is by "level",
 | |
| with high-level functions first, followed by groups of progressively
 | |
| lower-level functions. This makes it easy for the program's reader to
 | |
| see the top-down structure by reading from top to bottom.
 | |
| 
 | |
|   All function declarations and definitions should include a
 | |
| prototype.  Empty parentheses, e.g. "int foo();", do not include a
 | |
| prototype (they state that the function's parameters are unknown);
 | |
| write "void" in parentheses instead, e.g. "int foo(void);".
 | |
| 
 | |
|   Prototypes for static functions should either all go at the top
 | |
| of the file, separated into groups by blank lines.  Don't comment
 | |
| individual prototypes, but a comment on each group of prototypes is
 | |
| often appropriate.
 | |
| 
 | |
|   In the absence of good reasons for another order, the following
 | |
| parameter order is preferred.  One notable exception is that data
 | |
| parameters and their corresponding size parameters should be paired.
 | |
| 
 | |
|     1. The primary object being manipulated, if any (equivalent to the
 | |
|        "this" pointer in C++).
 | |
|     2. Input-only parameters.
 | |
|     3. Input/output parameters.
 | |
|     4. Output-only parameters.
 | |
|     5. Status parameter. 
 | |
| 
 | |
|   Example:
 | |
| 
 | |
|     /* Stores the features supported by 'netdev' into each of '*current',
 | |
|      * '*advertised', '*supported', and '*peer' that are non-null.  Each value
 | |
|      * is a bitmap of "enum ofp_port_features" bits, in host byte order.
 | |
|      * Returns 0 if successful, otherwise a positive errno value.  On failure,
 | |
|      * all of the passed-in values are set to 0. */
 | |
|     int
 | |
|     netdev_get_features(struct netdev *netdev,
 | |
|                         uint32_t *current, uint32_t *advertised,
 | |
|                         uint32_t *supported, uint32_t *peer)
 | |
|     {
 | |
|         ...
 | |
|     }
 | |
| 
 | |
| 
 | |
| FUNCTION PROTOTYPES
 | |
| 
 | |
|   Put the return type and function name on the same line in a function
 | |
| prototype:
 | |
| 
 | |
|     static const struct option_class *get_option_class(int code);
 | |
| 
 | |
| 
 | |
|   Omit parameter names from function prototypes when the names do not
 | |
| give useful information, e.g.:
 | |
| 
 | |
|     int netdev_get_mtu(const struct netdev *, int *mtup);
 | |
| 
 | |
| 
 | |
| STATEMENTS
 | |
| 
 | |
|   Indent each level of code with 4 spaces.  Use BSD-style brace
 | |
| placement:
 | |
| 
 | |
|     if (a()) {
 | |
|         b();
 | |
|         d();
 | |
|     }
 | |
| 
 | |
|   Put a space between "if", "while", "for", etc. and the expressions
 | |
| that follow them.
 | |
| 
 | |
|   Enclose single statements in braces:
 | |
| 
 | |
|     if (a > b) {
 | |
|         return a;
 | |
|     } else {
 | |
|         return b;
 | |
|     }
 | |
| 
 | |
|   Use comments and blank lines to divide long functions into logical
 | |
| groups of statements.
 | |
| 
 | |
|   Avoid assignments inside "if" and "while" conditions.
 | |
| 
 | |
|   Do not put gratuitous parentheses around the expression in a return
 | |
| statement, that is, write "return 0;" and not "return(0);"
 | |
| 
 | |
|   Write only one statement per line.
 | |
| 
 | |
|   Indent "switch" statements like this:
 | |
| 
 | |
|     switch (conn->state) {
 | |
|     case S_RECV:
 | |
|         error = run_connection_input(conn);
 | |
|         break;
 | |
| 
 | |
|     case S_PROCESS:
 | |
|         error = 0;
 | |
|         break;
 | |
| 
 | |
|     case S_SEND:
 | |
|         error = run_connection_output(conn);
 | |
|         break;
 | |
| 
 | |
|     default:
 | |
|         NOT_REACHED();
 | |
|     }
 | |
| 
 | |
|   "switch" statements with very short, uniform cases may use an
 | |
| abbreviated style:
 | |
| 
 | |
|     switch (code) {
 | |
|     case 200: return "OK";
 | |
|     case 201: return "Created";
 | |
|     case 202: return "Accepted";
 | |
|     case 204: return "No Content";
 | |
|     default: return "Unknown";
 | |
|     }
 | |
| 
 | |
|   Use "for (;;)" to write an infinite loop.
 | |
| 
 | |
|   In an if/else construct where one branch is the "normal" or "common"
 | |
| case and the other branch is the "uncommon" or "error" case, put the
 | |
| common case after the "if", not the "else".  This is a form of
 | |
| documentation.  It also places the most important code in sequential
 | |
| order without forcing the reader to visually skip past less important
 | |
| details.  (Some compilers also assume that the "if" branch is the more
 | |
| common case, so this can be a real form of optimization as well.)
 | |
| 
 | |
| 
 | |
| MACROS
 | |
| 
 | |
|   Don't define an object-like macro if an enum can be used instead.
 | |
| 
 | |
|   Don't define a function-like macro if a "static inline" function
 | |
| can be used instead.
 | |
| 
 | |
|   If a macro's definition contains multiple statements, enclose them
 | |
| with "do { ... } while (0)" to allow them to work properly in all
 | |
| syntactic circumstances.
 | |
| 
 | |
|   Do use macros to eliminate the need to update different parts of a
 | |
| single file in parallel, e.g. a list of enums and an array that gives
 | |
| the name of each enum.  For example:
 | |
| 
 | |
|     /* Logging importance levels. */
 | |
|     #define VLOG_LEVELS                             \
 | |
|         VLOG_LEVEL(EMER, LOG_ALERT)                 \
 | |
|         VLOG_LEVEL(ERR, LOG_ERR)                    \
 | |
|         VLOG_LEVEL(WARN, LOG_WARNING)               \
 | |
|         VLOG_LEVEL(INFO, LOG_NOTICE)                \
 | |
|         VLOG_LEVEL(DBG, LOG_DEBUG)
 | |
|     enum vlog_level {
 | |
|     #define VLOG_LEVEL(NAME, SYSLOG_LEVEL) VLL_##NAME,
 | |
|         VLOG_LEVELS
 | |
|     #undef VLOG_LEVEL
 | |
|         VLL_N_LEVELS
 | |
|     };
 | |
| 
 | |
|     /* Name for each logging level. */
 | |
|     static const char *level_names[VLL_N_LEVELS] = {
 | |
|     #define VLOG_LEVEL(NAME, SYSLOG_LEVEL) #NAME,
 | |
|         VLOG_LEVELS
 | |
|     #undef VLOG_LEVEL
 | |
|     };
 | |
| 
 | |
| 
 | |
| FILE NAMES
 | |
| 
 | |
|   Files and directories should be given short descriptive names,
 | |
| preferably matching the prefix of names in the file if applicable. File and
 | |
| directory names must use only lowercase letters and underscores, plus a period
 | |
| for the extension if any.
 | |
| 
 | |
| 
 | |
| SOURCE FILES
 | |
| 
 | |
|   Each source file should state its license in a comment at the very
 | |
| top, followed by a comment explaining the purpose of the code that is
 | |
| in that file. The comment should explain how the code in the file
 | |
| relates to code in other files. The goal is to allow a programmer to
 | |
| quickly figure out where a given module fits into the larger system.
 | |
| 
 | |
| #include directives should appear in the following order:
 | |
| 
 | |
|     1. The module's own headers, if any.  Including this before any other
 | |
|        header ensures that the module's header file is self-contained
 | |
|        (see HEADER FILES below).
 | |
| 
 | |
|     2. Standard C library headers and other system headers, preferably
 | |
|        in alphabetical order.  (Occasionally one encounters a set of
 | |
|        system headers that must be included in a particular order, in
 | |
|        which case that order must take precedence.)
 | |
| 
 | |
|     3. Other headers in alphabetical order.
 | |
| 
 | |
| 
 | |
| HEADER FILES
 | |
| 
 | |
|   Each header file should start with its license, as described under
 | |
| SOURCE FILES above, followed by a "header guard" to make the header
 | |
| file idempotent, like so:
 | |
| 
 | |
|     #ifndef NETDEV_H
 | |
|     #define NETDEV_H 1
 | |
| 
 | |
|     ...
 | |
| 
 | |
|     #endif /* netdev.h */
 | |
| 
 | |
|   Header files should be self-contained; that is, they should #include
 | |
| whatever additional headers are required, without requiring the client
 | |
| to #include them for it.
 | |
| 
 | |
|   Don't define the members of a struct or union in a header file,
 | |
| unless client code is actually intended to access them directly or if
 | |
| the definition is otherwise actually needed (e.g. inline functions
 | |
| defined in the header need them).
 | |
| 
 | |
|   Similarly, don't #include a header file just for the declaration of
 | |
| a struct or union tag (e.g. just for "struct <name>;").  Just declare
 | |
| the tag yourself.  This reduces the number of header file
 | |
| dependencies.
 | |
| 
 | |
| 
 | |
| TYPES
 | |
| 
 | |
|   Use typedefs sparingly.  Code is clearer if the actual type is
 | |
| visible at the point of declaration.  Do not, in general, declare a
 | |
| typedef for a struct, union, or enum.  Do not declare a typedef for a
 | |
| pointer type, because this can be very confusing to the reader.
 | |
| 
 | |
|   A function type is a good use for a typedef because it can clarify
 | |
| code.  The type should be a function type, not a pointer-to-function
 | |
| type.  That way, the typedef name can be used to declare function
 | |
| prototypes.  (It cannot be used for function definitions, because that
 | |
| is explicitly prohibited by C89 and C99.)
 | |
| 
 | |
|   You may assume that "char" is exactly 8 bits and that "int" and
 | |
| "long" are at least 32 bits.
 | |
| 
 | |
|   Don't assume that "long" is big enough to hold a pointer.  If you
 | |
| need to cast a pointer to an integer, use "intptr_t" or "uintptr_t"
 | |
| from <stdint.h>.
 | |
| 
 | |
|   Use the int<N>_t and uint<N>_t types from <stdint.h> for exact-width
 | |
| integer types.  Use the PRId<N>, PRIu<N>, and PRIx<N> macros from
 | |
| <inttypes.h> for formatting them with printf() and related functions.
 | |
| 
 | |
|   Use %zu to format size_t with printf().
 | |
| 
 | |
|   Use bit-fields sparingly.  Do not use bit-fields for layout of
 | |
| network protocol fields or in other circumstances where the exact
 | |
| format is important.
 | |
| 
 | |
|   Declare bit-fields to be type "unsigned int" or "signed int".  Do
 | |
| *not* declare bit-fields of type "int": C89 allows these to be either
 | |
| signed or unsigned according to the compiler's whim.  (A 1-bit
 | |
| bit-field of type "int" may have a range of -1...0!)  Do not declare
 | |
| bit-fields of type _Bool or enum or any other type, because these are
 | |
| not portable.
 | |
| 
 | |
|   Try to order structure members such that they pack well on a system
 | |
| with 2-byte "short", 4-byte "int", and 4- or 8-byte "long" and pointer
 | |
| types.  Prefer clear organization over size optimization unless you
 | |
| are convinced there is a size or speed benefit.
 | |
| 
 | |
|   Pointer declarators bind to the variable name, not the type name.
 | |
| Write "int *x", not "int* x" and definitely not "int * x".
 | |
| 
 | |
| 
 | |
| EXPRESSIONS
 | |
| 
 | |
|   Put one space on each side of infix binary and ternary operators:
 | |
| 
 | |
|     * / %
 | |
|     + -
 | |
|     << >>
 | |
|     < <= > >=
 | |
|     == !=
 | |
|     &
 | |
|     ^
 | |
|     |
 | |
|     &&
 | |
|     ||
 | |
|     ?:
 | |
|     = += -= *= /= %= &= ^= |= <<= >>=
 | |
| 
 | |
|   Avoid comma operators.
 | |
| 
 | |
|   Do not put any white space around postfix, prefix, or grouping
 | |
| operators:
 | |
| 
 | |
|     () [] -> .
 | |
|     ! ~ ++ -- + - * &
 | |
| 
 | |
| Exception 1: Put a space between the () used in a cast and the
 | |
| expression whose type is cast: (void *) 0.
 | |
| 
 | |
|   Break long lines before the ternary operators ? and :, rather than
 | |
| after them, e.g.
 | |
| 
 | |
|     return (out_port != VIGP_CONTROL_PATH
 | |
|             ? alpheus_output_port(dp, skb, out_port)
 | |
|             : alpheus_output_control(dp, skb, fwd_save_skb(skb),
 | |
|                                      VIGR_ACTION));
 | |
| 
 | |
| 
 | |
|   Do not parenthesize the operands of && and || unless operator
 | |
| precedence makes it necessary, or unless the operands are themselves
 | |
| expressions that use && and ||.  Thus:
 | |
| 
 | |
|     if (!isdigit((unsigned char)s[0])
 | |
|             || !isdigit((unsigned char)s[1])
 | |
|             || !isdigit((unsigned char)s[2])) {
 | |
|         printf("string %s does not start with 3-digit code\n", s);
 | |
|     }
 | |
| 
 | |
| but
 | |
| 
 | |
|     if (rule && (!best || rule->priority > best->priority)) {
 | |
|         best = rule;
 | |
|     }
 | |
| 
 | |
|   Do parenthesize a subexpression that must be split across more than
 | |
| one line, e.g.:
 | |
| 
 | |
|     *idxp = ((l1_idx << PORT_ARRAY_L1_SHIFT)
 | |
|              | (l2_idx << PORT_ARRAY_L2_SHIFT)
 | |
|              | (l3_idx << PORT_ARRAY_L3_SHIFT));
 | |
| 
 | |
|   Try to avoid casts.  Don't cast the return value of malloc().
 | |
| 
 | |
|   The "sizeof" operator is unique among C operators in that it accepts
 | |
| two very different kinds of operands: an expression or a type.  In
 | |
| general, prefer to specify an expression, e.g. "int *x =
 | |
| xmalloc(sizeof(*x));".  Always parenthesize the operand to sizeof and
 | |
| don't leave a space between the operator and opening parenthesis.
 | |
| 
 | |
|   When using a relational operator like "<" or "==", put an expression
 | |
| or variable argument on the left and a constant argument on the
 | |
| right, e.g. "x == 0", *not* "0 == x".
 | |
| 
 | |
| 
 | |
| GOTO
 | |
| 
 | |
| Gotos are acceptable as a means of collecting control across multiple
 | |
| operations which may result in a terminal error. If any operation fails,
 | |
| control is transfered to the end of the function where error handling
 | |
| and unwinding is done. For examples, see the implementation of the
 | |
| Forwarding component in the LRI in forwarding.c. See also Chapter 7
 | |
| of the Linux Kernel coding style document at
 | |
| http://www.kernel.org/doc/Documentation/CodingStyle.
 | |
| 
 | |
| 
 | |
| BLANK LINES
 | |
| 
 | |
|   Put one blank line between top-level definitions of functions and
 | |
| global variables.
 | |
| 
 | |
| 
 | |
| C DIALECT
 | |
| 
 | |
|   Some C99 features are OK because they are widely implemented even in
 | |
| older compilers:
 | |
| 
 | |
|     * Flexible array members (e.g. struct { int foo[]; }).
 | |
| 
 | |
|     * "static inline" functions (but no other forms of "inline", for
 | |
|       which GCC and C99 have differing interpretations).
 | |
| 
 | |
|     * "long long"
 | |
| 
 | |
|     * <stdint.h> and <inttypes.h>.
 | |
| 
 | |
|     * bool and <stdbool.h>, but don't assume that bool or _Bool can
 | |
|       only take on the values 0 or 1, because this behavior can't be
 | |
|       simulated on C89 compilers.
 | |
| 
 | |
|   As a matter of style, avoid // comments.
 | |
| 
 | |
|   Avoid using GCC extensions unless you also add a fallback for
 | |
| non-GCC compilers.  You can, however, use GCC extensions and C99
 | |
| features in code that compiles only on GNU/Linux (such as
 | |
| lib/netdev-linux.c), because GCC is the system compiler there.
 | 
