Code Guidelines

From Vifm Wiki
Revision as of 13:24, 9 August 2015 by Xaizek (talk | contribs) (→‎Braces: Note mandatory use of braces)
Jump to navigation Jump to search

General

Encoding

UTF-8, but without BOM.

Line endings

Unix. With an empty line at end of file.

Trailing whitespace

Strictly forbidden.

Line length limitation

Up to 80 characters. Verbose definitions of certain data structures can exceed this limit.

Header and footer

GNU comment

New files should have header that states license applied, copy from other files and update the line with copyright.

Vim modeline

Each source file has Vim modeline settings to encode style when editing with Vim, this should be copied into new files.

Empty lines

No more than one consequent.

Indentation

General

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

For wrapped lines

Switch statement

case is indented as well as what goes after it, e.g.:

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

Braces

Presence

Even single-statement blocks should be enclosed in braces, like in

if(cmd == NULL)
{
    return;
}

Placement

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

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

Comments

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

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

Naming

Functions and variables

Words in lower case separated with underscores.

Macros

Words in upper case separated with underscores.

Types

Usualy have _t suffix.

Prefixes

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

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

Order of groups

  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

  1. Directories go first
  2. All includes are in alphabetic order

Additional information

It's a good point to write list of used symbols in comments along with include of system headers.

Header files

Header guard

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

Other

Order of declarations

  1. Types
  2. Functions
  3. Variables

Order of functions

When possible, callee should follow caller in the code.

Size of function body

Type declarations

Pointers

In return types:

wchar_t * to_wide(const char s[]);

For variables:

wchar_t *result = NULL;

Pointers to arrays

In parameter list, such pointers should be written as

type name[]

instead of

type *name

Enumerations

Structures

Unions

Other typedefs

Variable declarations

Using size_t type

Arrays in function argument list

Constness of function arguments

Constness of local variables

Literals

Character literals

Comparison with zero or non zero

C standard and GNU extensions

It's mostly GNUC. Variable declarations are like in C90. Designated initializers and expression statements are used in the code.