About the Guidelines
Although most open source projects do not enforce a coding style on its developers, the TinyKRNL project recognizes the importance of a rigid and commercial-like organization and structure which sets the project apart from most other typical FOSS environments. The project believes that by enforcing a limited amount of rules to aspects such as code style and quality, this will increase code readability, aid in bug hunting and documentation, as well as resolve many issues which other projects face.
The guidelines used by the project are standard C coding styles and should be familiar to most Windows developers. However, they may be surprising to UNIX-style developers, which use an entirely different set of rules. In any case, we have found these rules to be generally well liked by most people, and extremely readable for all involved.
^ TOPFunction Style
Function style is defined by two things: the actual function declaration, and, for TinyKRNL, the obligatory comment header describing the function.
- Function declaration: The generic template for any function is
as follows:
RETURN_TYPE
FunctionName(PARAMETER_ANNOTATIONS PARAMETER_TYPE ParameterName1,
PARAMETER_ANNOTATIONS PARAMETER_TYPE ParameterName2)
{
<function starts here>;
}
In Windows style coding, almost all types are in CAPS. Therefore, void is VOID and int is INT. TinyKRNL also enforces the use of CamelCase (sometimes called PascalCase) for function names, parameter names and local variable names. Parameter annotations refer to another Windows-centric style in which parameters are marked as IN and/or OUT and OPTIONAL, if necessary. These annotations are readable cues on wether this function uses the parameters for input or output, and wether or not they are optional. Here is a complete example for a function which returns the number of apples in a tree, and can optionally also return the number of branches in the tree.
ULONG
CountApples(IN PTREE_OBJECT TreeWithApples,
OUT PULONG NumberOfBranches OPTIONAL)
{
<function starts here>;
}
- Comment header: The comment header for the
CountApples function would be as follows:
/*++
* @name CountApples
*
* The CountApples routine counts the number of apples in a tree and, optionally,
* returns the number of branches.
*
* @param TreeWithApples
* Pointer to a tree object containing the apples.
*
* @param NumberOfBranches
* Optional pointer to the value where to return the number of branches.
*
* @return The number of apples in this tree.
*
* @remarks To count the apples in an entire forest, use the CountApplesInForest
* routine instead.
*
*--*/
If there are no parameters and/or return value and/or remarks, simply write "None."
Code Style
Code style refers to the ensemble of rules that must be respected when writing code inside TinyKRNL. Here is a generic overview:
- All lines must be indented with four spaces.
- Lines must not be longer then 80 columns (characters). To avoid this, break up function calls so that each parameter is aligned below the next. If the line contains no breakable arguments, break it after any other component such as a comma, an operator, a period, etc.
- Braces must always be on a new line, and not following or preceding a for, if, else, etc...
- All local variables must be defined at the beginning of a function, and not in later constructs.
- All local variables must be CamelCased.
- Every line of code, or block of code achieving a combined operation (3 lines max) must be commented.
- Comments are always in // blocks, with empty // lines before and after the comment, for a total size of at least 3 lines per comment.
- During operations requiring the usage of boolean or logical comparisons, each comparison block should be enclosed in parens if more then one comparison is being done.
- Do not put spaces between the parenthesis starting a function call and the first parameter, nor between the last parameter and the parenthesis closing the function call.
Header Style
Header style refers to how function prototypes, type definitions and other information present in headers should be organized.
For prototypes or function types, the CountApples function would be
defined as follows:
ULONG
CountApples(
IN PTREE_OBJECT TreeWithApples,
OUT PULONG NumberOfBranches OPTIONAL
);
The TREE_OBJECT type would be defined like this:
typedef struct _TREE_OBJECT
{
ULONG Branches;
ULONG Apples;
} TREE_OBJECT, *PTREE_OBJECT;
Additionally, the following rules apply:
- All type definitions should be grouped together. A short comment block describing the type is preferable. As well, a comment block marking the beginning of the type definition section should be present.
- Likewise, all #defines should be together, as well as all prototypes. The former should be grouped together with a comment block above them if applicable. All defines in the same header should be aligned with their expansion. The same goes for macros.
- Prototypes should be organized by the file in which the function is present. They should not be documented apart from a comment block separating each file section.
- All types and prototypes in a component should be defined in a single header unless there is an overwhelming need to create one or more internal headers.
- All components must have a precompiled header named precomp.h.
Generic Rules
Finally, the following rules apply to TinyKRNL components in general:
- The file names, function names, and location inside the TinyKRNL tree must match those of the Windows 2003 Service Pack 1 Tree.
- All files must have the following file header as a template:
/*++
Copyright (c) Author Name. All rights reserved.
THIS CODE AND INFORMATION IS PROVIDED UNDER <LICENSE TYPE>.
PLEASE READ THE FILE <LICENSE FILE> IN THE TOP LEVEL DIRECTORY.
Module Name:
ModuleName.c
Abstract:
Description of either the component or this specific module.
Environment:
<Kernel mode> or <User mode>
Revision History:
SVN Committer - Summary of change(s) - DD-Mon-YY
--*/
#include "precomp.h"