2022-06-08 03:45:28 -04:00
|
|
|
Common
|
|
|
|
------
|
|
|
|
|
|
|
|
* Add your name to [COPYING](/COPYING).
|
2022-06-25 16:28:28 -04:00
|
|
|
* Don't add your name to `AUTHORS` - it's for maintainers.
|
2022-06-22 05:14:11 -04:00
|
|
|
* Add copyright notice in the beginning of changed files except the headers.
|
2022-06-12 09:52:40 -04:00
|
|
|
* If you change the behavior (even just fix a bug) of **libkernaux** (stable) or
|
|
|
|
[libc](/libc), add a record to [ChangeLog](/ChangeLog).
|
2022-06-08 03:45:28 -04:00
|
|
|
|
2022-06-25 16:28:28 -04:00
|
|
|
Prohibitions:
|
|
|
|
|
|
|
|
* Don't commit binary files
|
|
|
|
* Don't commit configuration files of your editor or IDE
|
|
|
|
* Don't use encodings other than ASCII and UTF-8
|
|
|
|
* Don't use alphabets other than Latin
|
|
|
|
* Don't use languages other than English
|
|
|
|
* Don't use tabulations (I don't hate tabs, but people can not use them
|
|
|
|
properly)
|
|
|
|
* Don't leave trailing whitespaces
|
|
|
|
* Don't forget the newline character in the end of files
|
|
|
|
|
|
|
|
The following statements are recommendations, but highly encouraged:
|
|
|
|
|
|
|
|
* Write documentation
|
|
|
|
* Write tests
|
|
|
|
* Keep lines less than 80 characters long for better experience on split screen
|
|
|
|
|
|
|
|
### Programming mistakes
|
|
|
|
|
|
|
|
* Always check documentation, manuals and specifications
|
|
|
|
|
|
|
|
Avoid stupid errors with:
|
|
|
|
|
|
|
|
* Manual memory management
|
|
|
|
* `malloc` may return `NULL`
|
|
|
|
* Memory leak (forget to `free`)
|
|
|
|
* Use after `free`/`realloc`
|
|
|
|
* Double `free`/`realloc`
|
|
|
|
* `free`ing/`realloc`ating unallocated memory
|
|
|
|
* Changing the original pointer to the allocated memory (use `const`!)
|
|
|
|
* `NULL` pointers and `nil`/`None`/whatever objects
|
|
|
|
* Division by zero
|
|
|
|
* Pointer arithmetic - consider type size
|
|
|
|
* Type sizes (like `long` on 32-bit and 64-bit)
|
|
|
|
* Integer arithmetic overflow
|
|
|
|
* Bit shift
|
|
|
|
* Endianness (byte order)
|
|
|
|
* Data packing
|
|
|
|
* Data alignment
|
|
|
|
* Thread safety
|
|
|
|
* Undefined behavior
|
|
|
|
* Logical expressions (tautology, whatever)
|
|
|
|
* Checking for an error (return value, pointer argument, whatever)
|
|
|
|
* Use of not fully initialized data
|
|
|
|
* Not reading beyond a buffer, array or string
|
|
|
|
* The index of the last item, which is less than the buffer size
|
|
|
|
* Negative indices
|
|
|
|
* The terminating null character in a string
|
|
|
|
* Allowed values of arguments
|
|
|
|
* Possible values of parameters
|
|
|
|
* Operator precedence
|
|
|
|
* Default case in switch statements
|
|
|
|
* Braces (curly brackets) around code blocks
|
|
|
|
|
2022-12-01 14:42:43 -05:00
|
|
|
### Things to review periodically
|
|
|
|
|
|
|
|
* `git grep -i fixme`
|
|
|
|
* `git grep -i todo`
|
|
|
|
* `git grep -i cppcheck-suppress`
|
|
|
|
* `git grep -i rubocop:disable`
|
|
|
|
|
2022-06-08 03:45:28 -04:00
|
|
|
|
|
|
|
|
2022-05-30 17:13:43 -04:00
|
|
|
C language
|
|
|
|
----------
|
|
|
|
|
2022-06-25 16:28:28 -04:00
|
|
|
Use **cppcheck**.
|
|
|
|
|
2022-06-22 05:14:11 -04:00
|
|
|
* Name regular functions (*not methods*) and variables in lower snake case
|
|
|
|
(example: `foo_bar`).
|
|
|
|
* Name macros in upper snake case (example: `FOO_BAR`).
|
|
|
|
* Name types (*structures, unions, enumerations and type definitions*) in Pascal
|
|
|
|
case (example: `FooBar`).
|
|
|
|
* Name nested types in Pascal case and with the prefix of the surrounding type
|
|
|
|
in Pascal case, separate type names with underscores (example:
|
|
|
|
`FooBar_CarCdr`).
|
|
|
|
* Name methods (*functions that belong to a specific type*) in lower snake case
|
|
|
|
and with the prefix of the type name in Pascal case (example:
|
|
|
|
`FooBar_car_cdr`).
|
|
|
|
|
|
|
|
* Name public (*defined in the headers and exported as symbols*) regular
|
|
|
|
functions (*not methods*) and variables with the prefix `kernaux_` (example:
|
|
|
|
`kernaux_foo_bar`).
|
|
|
|
* Name public (*defined in the headers*) macros with the prefix `KERNAUX_`
|
|
|
|
(example: `KERNAUX_FOO_BAR`).
|
|
|
|
* Name public (*defined in the headers*) types with the prefix `KernAux_`
|
|
|
|
(example: `KernAux_FooBar`).
|
|
|
|
* Name public (*defined in the headers*) with the prefix `KernAux_` and with the
|
|
|
|
prefix of the surrounding type, separate type names with underscore (example:
|
|
|
|
`KernAux_FooBar_CarCdr`).
|
|
|
|
* Name public (*defined in the headers*) methods with the prefix `KernAux_` and
|
|
|
|
with the prefix of the type name (example: `KernAux_FooBar_car_cdr`).
|
|
|
|
|
2022-06-15 06:10:44 -04:00
|
|
|
* Create `typedef`s with the names of related `struct`s. Use this name with a
|
|
|
|
prefix `struct` to declare the data itself, withoth the prefix to declare
|
|
|
|
a pointer or an array:
|
|
|
|
|
|
|
|
```c
|
|
|
|
typedef struct FooBar { int car; } *FooBar;
|
|
|
|
|
|
|
|
static struct FooBar FooBar_create();
|
2022-06-15 06:14:37 -04:00
|
|
|
static void FooBar FooBar_init(FooBar foobar);
|
2022-06-15 06:10:44 -04:00
|
|
|
|
2022-06-15 06:14:37 -04:00
|
|
|
static void FooBar_do_something(FooBar foobar);
|
2022-06-15 06:10:44 -04:00
|
|
|
|
2022-06-15 06:14:37 -04:00
|
|
|
// Initialize:
|
2022-06-15 06:10:44 -04:00
|
|
|
struct FooBar foobar = FooBar_create();
|
2022-06-15 06:14:37 -04:00
|
|
|
// or
|
|
|
|
struct FooBar foobar;
|
|
|
|
FooBar_init(&foobar);
|
|
|
|
|
|
|
|
// Use:
|
2022-06-15 06:10:44 -04:00
|
|
|
FooBar foobar_ptr = &foobar;
|
|
|
|
FooBar_do_something(&foobar);
|
|
|
|
```
|
|
|
|
|
|
|
|
```c
|
|
|
|
typedef struct FooBar { int car; } FooBar[1];
|
|
|
|
|
|
|
|
static struct FooBar FooBar_create();
|
|
|
|
static void FooBar FooBar_init(FooBar foobar);
|
|
|
|
|
|
|
|
static void FooBar_do_something(FooBar foobar);
|
|
|
|
|
2022-06-15 06:14:37 -04:00
|
|
|
// Initialize:
|
2022-06-15 06:10:44 -04:00
|
|
|
FooBar foobar = { FooBar_create() };
|
|
|
|
// or
|
|
|
|
FooBar foobar;
|
|
|
|
FooBar_init(foobar);
|
|
|
|
|
2022-06-15 06:14:37 -04:00
|
|
|
// Use:
|
2022-06-15 06:10:44 -04:00
|
|
|
FooBar_do_something(foobar);
|
|
|
|
```
|
2022-05-30 17:13:43 -04:00
|
|
|
|
2022-06-25 16:28:28 -04:00
|
|
|
* Mark variables and parameters with `const` if you don't plan to modify them
|
|
|
|
* Only omit braces (curly brackets) of a block if it's statement is placed on
|
|
|
|
the same line as conditional statement:
|
|
|
|
|
|
|
|
```c
|
|
|
|
// Good:
|
|
|
|
if (foo) return bar;
|
|
|
|
if (foo) {
|
|
|
|
return bar;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bad:
|
|
|
|
if (foo)
|
|
|
|
return bar;
|
|
|
|
```
|
|
|
|
|
2022-05-30 17:13:43 -04:00
|
|
|
|
|
|
|
|
|
|
|
Python
|
|
|
|
------
|
|
|
|
|
|
|
|
Nothing here yet.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ruby
|
|
|
|
----
|
|
|
|
|
2022-06-25 16:28:28 -04:00
|
|
|
* Freeze objects if you don't plan to modify them
|
|
|
|
|
2022-05-30 17:13:43 -04:00
|
|
|
### Matz's Ruby interpreter
|
|
|
|
|
2022-06-12 06:36:10 -04:00
|
|
|
Use **RuboCop**. See [bindings/ruby/.rubocop.yml](/bindings/ruby/.rubocop.yml)
|
2022-05-30 17:13:43 -04:00
|
|
|
|
|
|
|
### mruby
|
|
|
|
|
2022-06-12 06:36:10 -04:00
|
|
|
Use **RuboCop**. See [bindings/mruby/.rubocop.yml](/bindings/mruby/.rubocop.yml)
|
2022-05-30 17:13:43 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rust
|
|
|
|
----
|
|
|
|
|
2022-06-12 06:36:10 -04:00
|
|
|
Use **rustfmt** and **Clippy**.
|
2022-06-08 21:25:27 -04:00
|
|
|
See [bindings/rust/rustfmt.toml](/bindings/rust/rustfmt.toml)
|