# Programming Style/Code Formatting

[Programming language](programming_language.md) practically always leaves the programmer some [freedom](freedom.md) of styling that can increase (but also decrease) the aesthetic quality and readability of code, just like a writer has freedom in typesetting and choosing different words to express the same idea. As an example we can choose the variable names at our leisure without affecting how the program functions, expressions may include extra unnecessary brackets for better clarity or leave them out for shorter code and brevity, we can (and should) inserting [comments](comment.md), add proper indentation and whitespaces and so on. This gives rise to various programming styles; typically a programmer develops or adopts his own style over time, a "handwriting" of sort, but in a team compromises have to be found and everyone must temporarily conform to the same agreed style so as to preserve consistency and [readability](readability.md), just like artists have to follow the same visual style as part of larger collaborative work. Some project, e.g. [Linux](linux.md), have evolved quite good, tested and de facto standardized styles, so instead of inventing a custom style (which may not be as easy as it sounds) one may adopt some of the existing ones. While formatting and naming may not appear to be so important at first, it mustn't be underestimated as readability issues typically start to show later on as the project grows. On the other hand, however, it's not so difficult to reformat even a relatively large codebase in later stages ([regular expressions](regex.md) and similar tools can help with this very well), it's definitely much easier than reworking the code's architecture.

There exist automatic code formatters, they are often called **code beautifiers**. But not everything can be automated, for example a program will hardly comment your code, or inserting empty spaces to separate logically related parts of a sequential code is also something that human like intelligence is needed for.

## Recommended LRS C Programming Style/Formatting

Here we propose a programming style and C code formatting you may use in your programs. { It's basically a style I personally adopted and fine-tuned over many years of my programming. ~drummyfish } Remember that nothing is set in [stone](rock.md) (except that you mustn't use tabs), the most important rule of style is to maintain consistency within a single [project](project.md) and to actually think about why you're doing things the way you're doing them. Sticking to the standard presented here will gain you advantages such as increased readability for others already familiar with the same style and avoiding falls into traps of short-sighted decisions, e.g. regarding identifiers. Try to think from the point of view of a programmer who gets just your source code without any way to communicate with you, make his life as easy as possible. Also assume he's reading your code on a calculator. The LRS style/formatting rules follow:

- **Respect the [LRS](lrs.md) design principles** ([KISS](kiss.md), no [OOP](oop.md), avoid dependencies such as [stdlib](stdlib.md) etc.).
- **Indentation: use two spaces, NEVER use [tabs](tab.md)**. Why? Tabs are ugly, tricky (look the same as spaces) non-standard behaving characters (behavior is dependent on editor and settings, some processors will silently convert tabs and spaces, copy-paste may do so also etc.), they don't carry over to some platforms (especially paper), some very simple platforms may not even support them; your source will contain spaces either way, no need to insert additional blank character.
- **Limit source code width to 80** columns or similar value. If the line is a single command, e.g. a function call or expression, that would be too long, just break it and somewhere before the limit and put the rest on the next line, possibly indenting the below lines one level further. Keep in mind the source may be edited on computers with small screens (like old [thinkpads](thinkpad.md), especially within context of LRS) with a screen split vertically to two or more columns.
- Write **opening and closing curly brackets on their own lines, in the same columns**, e.g.:

```
if (a == b)
{
  doSomething();
  doSomething2();
}
else
{
  doSomethingElse();
  doSomethingElse2();
}
```

- **Omit curly brackets if you can** (e.g. with a single command in the block). However write them where not doing so is likely to cause confusion or syntax errors.
- **Use normal brackets to make precedence and intention clearer** even if they would be unnecessary, don't flex by writing an expression with confusing precedence that saves 4 text characters. For example it may be better to write `(a && b) || c` rather than `a && b || c`.
- **identifiers/names**:
  - **Use `camelCase` for variables and functions** (e.g. `myVariable`). Global and big-scope variables should have a greatly descriptive, self-documenting name, even if long (e.g. `getTicksSinceStart`, `countryAreaKMSquared`), local/short-scope identifiers can be shorter (e.g. `argBackup` within a single function), even just one letter (e.g. `i` within a single loop).
  - **Use `CapitalCamelCase` for data types** (e.g. `ImaginaryNumber`, `GameState` etc.).
  - **Use `ALL_CAPS_SNAKE_CASE` for macros and constants** (e.g. `PI`, `MIN`, `LOG_ERROR`, ...).
  - It is advised that for your project you come up with a **three letter namespace prefix** that will come in front of your global identifiers. (E.g. [small3dlib](small3dlib.md) uses the prefix `S3L_`, [SDL](sdl.md) uses `SDL` etc.). If you choose a prefix `XYZ_`, prepend it to all global identifiers, it will prevent name clashes and help readability, e.g. when writing a renderer you will export identifiers such as `XYZ_init`, `XYZ_draw`, `XYZ_setPixel`, `XYZ_Model3D` etc. Do NOT use the prefix in local variables (inside functions, loops etc.).
  - **Prefix private global identifiers with `_`**, e.g. `_tmpPointerBackup`; with the above mentioned namespace prefix this will look e.g. like this: `_XYZ_tmpPointerBackup`. 
- **Use spaces** to make code more readable, so e.g. `int x = 10, y = 20;` instead of `int x=10,y=20;`, write space between `if` and its condition etc.
- **Use verbs for [functions](function.md), nouns for variables** and keep consistency, e.g. a function should be named `getTimeMS` while a variable will be named `timeMS`. Functions are to be formatted like this:

```
void doSomethingCool(int a, int b, int c)
{
  // ...
}
```

- **Name from general to specific**, e.g. `getCountryTimezone` and `getCountryCapital` instead of `getTimeZoneOfCountry`, `getCapitalOfCountry` etc. This helps with code completion systems. It's not always exactly clear, you may also decide to go for `countryGetTimezone` etc., just keep it consistent.
- **Switch** shall always have the *default* label. The statements may be formatted e.g. like this:

```
switch (myVariable)
{
  case 0:
    doSomething();
    break;

  case 1:
    doSomethingElse();
    break;

  case 2:
  {
    int a = x + y;
    doSomethingCool(a);
    break;
  }

  default:
    break;
}

// or even (depending on how long the sections are)

switch (myVariable2)
{
  case 0: doSomething1(); break;
  case 1: doSomething2(); break;
  case 2: doSomething3(); break;
  case 3: doSomething4(); break;
  default: break;
}
```

- **Filenames**: always use only lowercase letters (some older systems just know one case, don't confuse them), either use `camel_case.ext` or `nocase.ext`.
- **Use blank lines** to logically group relevant lines of code. E.g.:

```
int a = x;
char b = y;
double q;

doSomething(a);

c += 3 * a;
d -= b;

if (c < d)
  a = b;
```

- Each file shall have a **global [comment](comment.md)** at the top with at least: short description of the file's purpose (this is almost always missing in mainstream), short documentation, [license](license.md), the author(s) and year of creation.
- **Use [comments](comment.md)** to make your code better readable and searchable with things like [grep](grep.md) (add keywords to relevant parts of code, e.g. comment `// player shoots` to code implementing player shooting etc.). **Use [doxygen](doxygen.md) style comments** if you can, it costs nothing and allows auto documentation.
- **TODOs and WIPs are good**.
- **Don't use [enums](enum.md)**, use `#define`s.
- **Global variables are great**, use them. **Long functions are fine**. [Repeating yourself](dry.md) may also be fine if it's something like 3 lines of code and the alternative would be too complex (but things like variadic macros can usually solve even these cases, always think hard in these cases).
- **Adhere to C99  or C89 standard**. It's ideal if your code is valid in both and maybe even more standards, AND in [C++](cpp.md) as well.
- **Try to not create many source files**, many times your project can very well be in a single file which is the ideal case -- it will make it compile VERY fast, possibly be even better optimized (the compiler sees the whole code) and it will be easy to compile, it's basically a win-win-win-win-win-win-win scenario. Create **[header only libraries](header_only.md)** If you have multiple files, keep them in the same directory and try to have just a **[single compilation unit](single_compilation_unit.md)** (only one .c file with several .h files). Try to make files no longer than 10k lines.
- **Use the LRS [version numbering](version_numbering.md) system**.
- **Never use non-[ASCII](ascii.md) characters in your source code**. Just don't, there is basically never any need for it.
- **Don't depend on any compiler extensions!** For maximum portability minimize [dependencies](dependency.md), i.e. don't RELY on things like GNU C extensions, POSIX extensions (things like `_POSIX_C_SOURCE`, `_XOPEN_SOURCE` etc.). You MAY use them, but always do so in a way that makes it easy to get rid of them -- for example do not use macros such as `PATH_MAX` directly, always define your own macro, e.g. `#define MYLIB_PATH_MAX PATH_MAX` and only use that -- this way you may easily switch to e.g. hardcoded limit if the macro isn't available on some system. Similarly with anything else: if your program is using a feature specific to a compiler, operating system, some extra third party standard and so on, always offer an easy way of disabling or replacing it ([preprocessor](preprocessor.md) is very good for this).
- ...

### Example

Here is a short example applying the above shown style:

```
TODO (for now see LRS projects like Anarch, small3dlib, SAF etc.)
```
