diff options
author | Chad Versace <chad.versace@linux.intel.com> | 2012-04-11 15:55:53 -0700 |
---|---|---|
committer | Chad Versace <chad.versace@linux.intel.com> | 2012-04-11 18:05:26 -0700 |
commit | 59b0c65fe72ebbd17256fd83b2814d9cdeb05eed (patch) | |
tree | fe611f0dc8f77c069a162082a48e7df1b99e15b4 | |
parent | b3db66fae0f0c92d86d8f932de656660cd36d50c (diff) |
doc: Add code style guidelines
Add file doc/code-style.txt. If any contributor has a style question,
hopefully this doc will answer it.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
-rw-r--r-- | doc/code-style.txt | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/doc/code-style.txt b/doc/code-style.txt new file mode 100644 index 0000000..2d12598 --- /dev/null +++ b/doc/code-style.txt @@ -0,0 +1,271 @@ +Waffle's coding style is heavily influenced by the Linux kernel and XCB. + +When in doubt, follow the style of nearby code. + + +Naming +====== + +All symbols exposed in the public API must be prefixed with `waffle_` or +`WAFFLE_`. + +No camelCase, itIsSoHardToRead, especiallyWhenTheVariableNameContainsAnUpperCaseAcronym. + +Function and variable names are lower_case_with_underscores. + +Enum and macro names are UPPER_CASE_WITH_UNDERSCORES. + +Don't use typedefs without a strong reason. They more often degrade code's +readability than improve it. + +Balance abbreviation with readability. A variable named number_of_objects is +too verbose; nobjs is too obscure; num_objects and num_objs are just right. + + +Object orientated design +======================== + +Much of Waffle's code adheres to an object oriented design. Not only does this +influence Waffle's architectural design, but also its naming conventions and code +organization. + +For this discussion, we will use `struct waffle_window` as an example. It is +implemented in the files + + /include/waffle/waffle_window.h + /src/waffle/api/waffle_window.c + +A class's header and source file have the same name as the class. For example, +waffle_window.h and waffle_window.c. + +Method names follow the convention of `typename_operation`. This makes it +immediately obvious on what the function acts and in which file the function +is defined. + + good: waffle_window_create + good: waffle_window_swap_buffers + + bad: waffle_create_window + +If a function is a plain ole procedure, it follow the naming convention +`prefix_action_object`. The following example is taken from +/src/waffle/egl/egl_no_template.c. + + good: egl_create_config + bad: egl_config_create // this looks like a method + +A method's first argument is the object on which it acts, and is named 'self'. +Exceptions are "static" methods, such as creation methods. This makes it +immediately obvious which argument is the object acted upon. + + good: + struct waffle_window* + waffle_window_create(const char *name); + + bool + waffle_window_swap_buffers(struct waffle_window *self); + ^^^^ + + bad: + bool + waffle_window_swap_buffers(struct waffle_window *window); + + +Comments +======== + +Non-Doxygen comments begin with double '/'. Do not use '/*'-style comments. +There are special exceptions, such as when commenting items in a table. Use +your judgement. + + +Doxygen +------- + +Waffle uses Doxygen as a documentation generator. Doxygen comments begin with +triple '/' and use '@' as the Doxygen command prefix. + + /// @brief Make fantastic coffee with rainbows and strawberries. + /// + /// Only drink one cup per day. Otherwise, you may become too happy. + void + make_fancy_coffee( + struct coffee_mug *mug, + struct french_press *press, + struct sugar_dish *sugar); + +Separate the brief and full description with a newline, as above. Otherwise, +Doxygen becomes confused and coalesces the full into the brief. + + +Commenting branches +------------------- + +If a comment only applies to one branch of an if-statement, place the comment +in the branch. Otherwise, the code will repeats itself. + + good: + if (dishes_need_washing && time >= 2300) { + // It's too late to wash dishes. Defer them until morning. + defer_washing_dishes(); + sleep(); + } + else { + // Even if the dishes need washing, it's too early to be worried + // by them. Go do something fun. + ride_a_bike(); + } + + bad: + // If the dishes need washing, but it's too late to wash them, then + // defer them until morning. Otherwise, go do something fun. Even if + // the dishes need washing, it's too early to be worried by them. + if (dishes_need_washing && time >= 2300) { + defer_washing_dishes(); + sleep(); + } + else { + ride_a_bike(); + } + + +Indentation +=========== + +Indent 4 spaces. No tabs. + +Place a function's return type on its own line. This ensures that all function +names are aligned and makes it easier to quickly find a function when scanning +the source. + + void + make_coffee(int x, int y); + +If a function prototype has a longwinded parameter list, then indent it like this: + + void + make_fancy_coffee( + struct coffee_mug *mug, + struct french_press *press, + struct sugar_dish *sugar); + +When calling a function with a longwinded argument list, indent it in either +of two ways. + + do_amazing_incredible_thing_with_a_really_long_function( + rainbows, + unicorns, + strawberries, + unicycle); + + do_boring_thing(rocks, + toothbrush, + dust_pan, + traffic_jam); + +Indent cases in switch statements. The last case always requires a jump +(break, return, goto). + + switch (time) { + case 600: + case 1545: + wake_up(); + break; + case 1500: + case 2200: + sleep(); + break; + default: + breathe(); + break; + } + +Don't put multiple statements on a single line. + + if (condition) do_something; + to_do_or_not_to_do; + + +Braces +====== + +For all statements that require braces, the opening brace is on the same line +as the statement, except for function definitions, where the brace is on a +line of its own. + + if (condition) { + do_stuff(); + } + + void + make_fancy_coffee( + struct coffee_mug *mug, + struct french_press *press, + struct sugar_dish *sugar) + { + rush_or_be_late_to_work(); + } + +The closing brace is always on a line of its own. + + if (x) { + ... + } + else if (y) { + ... + } + else { + ... + } + +and + + do { + ... + } + while (condition); + + +Spaces +====== + +Leave no trailing whitespace on end of lines. This can cause spurious commit +conflicts. + +A single empty line separates function and struct defintions. + +Do not add spaces inside a parenthesized expression. + + bad: foo( x, y ); + +Place a space after these keywords: + if, switch, case, for, do, while + +For keywords that are typically used as functions, do not follow the keyword +with a space and do enclose the arguments with parentheses. The keywords are: + sizeof, typeof, alignof, __attribute__ + +When declaring a variable or argument with pointer type, the '*' goes adjacent +to the variable or argument name. + + void + make_fancy_coffee( + struct coffee_mug *mug, + struct french_press *press, + struct sugar_dish *sugar) + { + void *mystery_ingredient = mug + press + sugar; + ... + } + +No spaces around unary operators. + --y; + !z; + +No spaces around the structure member operators: '.' and '->'. + cow->tail + teapot.spout + +Place a single space before and after the binary operators. + a + b + x == y |