3.8 KiB
Contributing clixon code
The clixon project welcomes contributions from the community.
A contribution must follow the CLIXON licensing following the dual licensing: either Apache License, Version 2.0 or GNU General Public License Version 3.
#A CLA such as generated by eg https://contributoragreements.org may need to be signed.
C style
Clixon uses 4-char indentation, a la emacs "cc-mode".
Function declarations
Functions in C code are written as follows:
static int
myfn(int par1,
my_structure *par2)
{
int retval = -1;
my_structure *ms;
ms = NULL;
Notes:
- The return type of the function and all qualifers on first line (
static int) - Function name and first parameter on second line, thereafter each parameter on own line
- Each parameter indented to match the "longest" (
my_structure) - Pointer declarations written:
type *p, not:type* p. - All local variables in a function declared at top of function, not inline with C-statements.
- Local variables can be initialized with scalars or constants, not eg malloc or functions with return values that need to be checked for errors
- There is a single empty line between local variable declarations and the first function statement.
Function signatures are declared in include files or in forward declaration using "one-line" syntax, unless very long:
static int myfn(int par1, my_structure *par2);
Errors
Errors are typically declared as follows:
if (myfn(0) < 0){
clicon_err(OE_UNIX, EINVAL, "myfn");
goto done;
}
All function returns that have return values must be checked
Default return values form a function are:
0OK-1Fatal Error
In some cases, Clixon uses three-value returns as follows:
1OK0Invalid (and usually a cxobj* return value)-1Fatal error
Return values
Clixon uses goto:s only to get a single point of exit functions as follows::
{ int retval = -1;
...
retval = 0;
done:
return retval
}
Notes:
- Use only a single return statement in a function
- Do not use of goto:s in other ways
Comments
Use /* */. Use // only for temporal comments.
Do not use ======, >>>>> or <<<<<< in comments since git merge conflict uses that.
Documentation
How to document the code:
/*! This is a small comment on one line
*
* This is a detailed description
* spanning several lines.
*
* Example usage:
* @code
* fn(a, &b);
* @endcode
*
* @param[in] src This is a description of the first parameter
* @param[in,out] dest This is a description of the second parameter
* @retval 0 This is a description of the return value
* @retval -1 This is a description of another return value
* @see See also this function
*/
Testing
For a new feature, you need to write a CI test, including some functionality tests and preferably some negative tests. Tests are then run automatically as regression on commit by github actions.
These tests are also the basis for more extensive CI tests run by the project which include memory tests, vagrant tests on other platforms, coverage tests and occasional fuzzing with AFL.
In particular, a new feature must pass the memory tests.