Difference between revisions of "Code Guidelines"
(→C standard and GNU extensions: Allow variable declarations not at block beginning.) |
(→Order of declarations: Better title) |
||
Line 227: | Line 227: | ||
== Other == | == Other == | ||
− | === Order of declarations === | + | === Order of declarations in a file === |
# Types | # Types |
Latest revision as of 20:14, 21 June 2018
General[edit]
Encoding[edit]
UTF-8, but without BOM.
Line endings[edit]
Unix. With an empty line at end of file.
Trailing whitespace[edit]
Strictly forbidden.
Line length limitation[edit]
Up to 80 characters. Verbose definitions of certain data structures can exceed this limit.
[edit]
GNU comment[edit]
New files should have header that states license applied, copy from other files and update the line with copyright.
Vim modeline[edit]
Each source file has Vim modeline settings to encode style when editing with Vim, this should be copied into new files.
Empty lines[edit]
No more than one consequent.
Indentation[edit]
General[edit]
Tabulation, which can be followed by spaces to get something like this:
return (entry->type == FT_DIR)
|| (entry->type == FT_LINK &&
get_symlink_type(entry->name) != SLT_UNKNOWN);
For regular lines[edit]
For wrapped lines[edit]
Switch statement[edit]
case
is indented as well as what goes after it, except for very rare cases there is no need for empty lines betweencase
statements.- When present,
default
must be the last item and it should be separated with an empty line from the rest. - The last statement must have
break;
. - Non-obvious cases of intentional omitting
break
should be documented in a comment.
Example:
switch(scope)
{
case FLS_SELECTION:
move_cursor_out_of_scope(view, &is_entry_selected);
break;
case FLS_MARKING:
move_cursor_out_of_scope(view, &is_entry_marked);
break;
default:
assert(0 && "Unhandled file list scope type");
break;
}
Formatting[edit]
Braces[edit]
Presence[edit]
Even single-statement blocks should be enclosed in braces, like in
if(cmd == NULL)
{
return;
}
Placement[edit]
Braces are on their own lines, except for data assignment, so we have
/* Custom argument for is_in_list() function. */
typedef struct
{
int nitems; /* Number of items in the list. */
char **items; /* The list itself. */
}
list_t;
but:
const struct timeval ts_init = { .tv_sec = 0, .tv_usec = 1000 };
and
get_mount_point_traverser_state state = {
.type = MI_FS_TYPE,
.path = full_path,
.buf_len = sizeof(fs_name),
.buf = fs_name,
.curr_len = 0UL,
};
Spacing[edit]
Commas should be followed by a space.
Binary plus and minus signs should be surrounded with spaces.
Keywords that are followed by open parenthesis, like if
,
while
, switch
should not be separated with a space
from the parenthesis.
Alignment[edit]
Comments[edit]
Only multiline comments of C90 should be used.
/*
and */
, no //
allowed.
First letter must be capitalized.
Sentences should end with a dot.
No need for dedicated lines for /*
or */
.
Example:
/* Ensure trash directories exist, it might not have been called during
* configuration file sourcing if there is no `set trashdir=...` command. */
Function comments[edit]
Non-static functions should have comments in corresponding header. Static functions should be commented where they are defined.
Comments are of free form (not Doxygen), but should include two things:
- what the function does;
- what it returns on success and error (if return type is not
void
).
Example:
/* Checks whether pair is being used at the moment. Returns non-zero if so and
* zero otherwise. */
It should be "Checks" and "Returns", not "Check" and "Return".
Item comments of union, struct or enum[edit]
Naming[edit]
Functions and variables[edit]
Words in lower case separated with underscores.
Macros[edit]
Words in upper case separated with underscores.
Types[edit]
Usualy have _t
suffix.
Prefixes[edit]
Some units have prefix for all names defined in them, ideally all of them should have such prefixes, but it's not the case yet. When editing such units, preserve prefixes.
Function definitions[edit]
Return type should be on a separate line along with static
keyword:
void
get_perm_string(char buf[], int len, mode_t mode)
{
...
}
Include directives[edit]
Order of groups[edit]
- Header of the current file
- Third-party library headers in arbitrary order
- System headers
- Local headers
Order of elements within groups[edit]
- Directories go first
- All includes are in alphabetic order
Additional information[edit]
It's a good point to write list of used symbols in comments along with include of system headers.
Header files[edit]
Header guard[edit]
PREFIX ::= VIFM | VIFM_TESTS
{PREFIX}{__DIR_NAME}__FILE_NAME_H__
Example:
#ifndef VIFM__BRACKET_NOTATION_H__
#define VIFM__BRACKET_NOTATION_H__
...
#endif /* VIFM__BRACKET_NOTATION_H__ */
Tests[edit]
Other[edit]
Order of declarations in a file[edit]
- Types
- Functions
- Variables
Order of functions[edit]
When possible, callee should follow caller in the code.
Size of function body[edit]
Type declarations[edit]
Pointers[edit]
In return types:
wchar_t * to_wide(const char s[]);
For variables:
wchar_t *result = NULL;
Pointers to arrays[edit]
In parameter list, such pointers should be written as
type name[]
instead of
type *name
Enumerations[edit]
Structures[edit]
Unions[edit]
Other typedefs[edit]
Variable declarations[edit]
Using size_t type[edit]
Arrays in function argument list[edit]
Constness of function arguments[edit]
Constness of local variables[edit]
Literals[edit]
Character literals[edit]
Comparison with zero or non zero[edit]
C standard and GNU extensions[edit]
It's GNU dialect of C.
Variable declarations are mostly in C90 style and declared at the beginning of code blocks, but declarations after statements are allowed too.
Designated initializers, expression statements, _Exit()
and <stdint.h>
are also used in the code base.