Code Guidelines

From Vifm Wiki
Jump to: navigation, search

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.

Header and footer[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 between case 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]

  1. Header of the current file
  2. Third-party library headers in arbitrary order
  3. System headers
  4. Local headers

Order of elements within groups[edit]

  1. Directories go first
  2. 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[edit]

  1. Types
  2. Functions
  3. 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 mostly GNUC. Variable declarations are like in C90. Designated initializers, expression statements, _Exit() and <stdint.h> are used in the code.