# C Style Guide

This guide describes the style intended for use with the C track exercise example and test files.

The rules within this guide are in addition to, or to call out, those in the [Linux kernel coding style guide](https://www.kernel.org/doc/html/latest/process/coding-style.html).

## C Standard

Code should conform to the C99 standard, more formally known as ISO/IEC 9899:1999. POSIX, or otherwise non-standard library functions, types or other references that are external to the implementation should not be used.

## Names

In general, the names of types, variables, structures and files should use snake case with all letters in lower case and underscores `_` are used to separate name components.

```c
void some_foo_function(char * input_string, int input_string_length);
```

### Enums

Enum names should usually be singular rather than plural.

Enum labels should use snake case with all letters in upper case.

```c
enum heading {
    HEADING_NORTH,
    HEADING_EAST,
    HEADING_SOUTH,
    HEADING_WEST
}
```

### Macros

Macros defining constants are named using snake case with all letters in upper case.

```c
#define CONSTANT 0x4000
```

Upper-case snake case for macro names is appreciated, but macros resembling functions may be named in lower-case snake case.

### Types

The standard fixed-width types (in `stdint.h`) are preferred over basic integer types.

The type `bool` (from `stdbool.h`) is preferred over `_Bool`. 

Likewise, `size_t` and `ptrdiff_t` (of `stddef.h`) are preferred for representing memory-related quantities.

Types defined by a program using `typedef` should be named with a `_t` suffix. 
While aware that POSIX reserves the `_t` suffix, the track does not currently utilise POSIX.

## Parameters

Function parameters should be named in both the declaration and definition of all functions. This applies to both `.c` and `.h` files. 
The names used should match in all instances.
That is to say that while the following function prototype is valid C, the style is incorrect because the parameter is unnamed: `void foo(int);`.
The correct prototype, providing that all other declarations and the definition also use the parameter name `bar`, would be `void foo(int bar);`.

Where it is simpler or more appropriate to do so, parameters that require passing arguments by value rather than by pointer are preferred. Note especially that this includes `struct` type parameters.

In the case that a student is not expected to change the values of a pointer-type parameter within their implementation, that parameter should be `const` qualified.

## Indentation and Format

The repository uses the `indent` tool, as outlined in the [contributing guide](https://github.com/exercism/c/blob/master/docs/CONTRIBUTING.md).

The options described for use with indent there are `-linux -i3 -nut`. The `-linux` option is a shortcut that is equivelent to a secific fixed group of options. The combined equivalent options are `-nbad -bap -nbc -bbo -hnl -br -brs -c33 -cd33 -ncdb -ce -ci4 -cli0 -d0 -di1 -nfc1 -i3 -nut -ip0 -l80 -lp -npcs -nprs -npsl -sai -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -il1`.

What these options do is indicated by the [GNU `indent` manual](https://www.gnu.org/software/indent/manual/indent.html#SEC4), but is also described here for easy reference if editing files manually.

- `nbad` - Do _not_ force blank lines after every block of declarations
- `bap` - Force a black line after every function body
- `nbc` - Do _not_ force a newline after each comma in a declaration
- `bbo` - Prefer to break long lines before the boolean operators `&&` and `||`
- `hnl` - Honour newlines in the file by giving them the highest possible priority to break lines at
- `br` - Place an opening brace on the same line as the `if (condition)`
- `brs` - Place an opening brace on same line as `struct struct_name`
- `c33` - Put comments to the right of code in column 33
- `cd33` - Put comments to the right of the declarations in column 33
- `ncdb` - Do _not_ put comment delimiters on blank lines
- `ce` - Place the `else` on the same line as the preceding closing brace, so the it is 'cuddled' like so `} else {`
- `ci4` - Indent by 4 spaces for hard line-breaks within statements (continuation indentation)
- `cli0` - Indent case labels by 0 spaces to the right of the containing switch statement
- `d0` - Set indentation of comments, that are _not_ to the right of code, to 0 spaces.
- `di1` - Line up identifiers in the first column
- `nfc1` - Do _not_ format comments that are in the first column
- `i3` - Set the indentation level to 3 spaces
- `nut` - Use spaces instead of tabs
- `ip0` - Use 0 extra offset indentation for breaks between two or more parenthesis pairs `(...)`
- `l80` - The maximum length of a line of C code is 80, not including possible comments that follow it
- `lp` - Line up continued lines at parentheses
- `npcs` - Do _not_ put space between the name of the function being called and the ‘(’, eg `puts("Hi");` not `puts ("Hi");`)
- `nprs` - Do _not_ put a space after every '(' and before every ')'
- `npsl` - Put the type of a function on the same line as its name
- `sai` - Force a space between an `if` and the following parenthesis
- `saf` - Force a space between a `for` and the following parenthesis
- `saw` - Force a space between a `while` and the following parenthesis
- `ncs` - Do _not_ put a space after cast operators
- `sob` - Swallow (remove) any optional blank lines
- `nfca` - Do _not_ format any comments
- `cp33` - Put comments to the right of `#else` and `#endif` statements in column 33
- `ss` - On one-line `for` and `while` statements, force a blank before the semicolon, like so `while (condition) ;`
- `il1` - Set the offset for labels to column 1

## Test file layout

Each exercise's test file follows a particular layout. 
The layout is intended to both help contibutors to identify parts of the file, and to help learners to understand how the tests work.

Like most C source files, a test file begins with includes. 

```c
#include "vendor/unity.h"
#include "../src/file_under_test.h"
// any other includes here
```

The includes are then followed by the `setUp()` and `tearDown()` functions. 
So far, no exercise uses these (the function bodies are empty) yet they must remain in place to allow the test files to compile correctly across all platforms.

```c
void setUp(void)
{
}

void tearDown(void)
{
}
```

Next are any helper functions that are used by the test functions.
The names of such helper functions should not use the `test_` prefix.

Next are the test functions themselves. 
The names of these functions use a `test_` prefix.
Excepting the first, each test function should have `TEST_IGNORE();` as its first statement. 
The first occurrence of this should be followed by the line comment `// delete this line to run test`.
For example:

```c
void test_the_first(void)
{
   test_first_foo();
}

void test_the_second(void)
{
   TEST_IGNORE();               // delete this line to run test
   test_second_foo();
}

void test_the_third(void)
{
   TEST_IGNORE();
   char grade = 'A';
   test_third_foo(grade);
}
```

Last in the file is the `main()` function. 
The function body of main follows a particular layout itself. 
First a call to `UnityBegin()` followed by an empty line, then the tests. 
The last test is followed by another empty line and then a call to `UnityEnd()`, before returning.

```c
int main(void)
{
    UnityBegin("test/test_file_name.c");
    
    RUN_TEST(test_foo);
    RUN_TEST(test_bar);
    
    UnityEnd();
    return 0;
}
```