!THIS DOCUMENTATION IS A WORK IN PROGRESS!

Introduction

Noch (Not Chol) is an ever-growing bundle of convenient C libraries that enables developers to reduce code repetition. Noch addresses reoccurring cases like parsing command line arguments and abstracting filesystem functions, so you can get to what matters promptly.

These libraries are designed to be included and compiled alongside your code. Because most header files have a single corresponding source file, if that, statically or dynamically linking such is merely overkill.

Motivation

The driving force behind Noch stems from the repetitive nature of coding in C programs. I found myself writing the same functions across multiple projects. After a while there came a point where continuing this pattern any further was no longer practical. It was time to encapsulate these various functions once and for all, so came the birth of Noch (successor to Chol).

Usage

To use a library from noch, include its .h file for the declarations, and then in a source file include the .c file for the implementation.

For easier configuring, you can include all .h files in a single file and all .c in a single file. See the example below.

example.h


						

example.c


						

Libraries

Config

To allow for the most flexibility, Noch provides several macros that can be redefined to extend and/or alter functionality. These macros can be defined prior to or following any included Noch headers. Here is an example using the NOCH_ASSERT macro from <noch/internal/assert.h>:

Example


						

The entire Noch library will use this assert rather than the default. You can find the default definitions of this macro and others here in the internal folder. By default, these macros use functions from the C standard library.

Macro NOCH_DEF

#define NOCH_DEF

Included in front of Noch function definitions.

Macro NOCH_ASSERT

#define NOCH_ASSERT(EXPR) assert(EXPR)

Used for assertions within Noch implementations.

Parameters

Name Description
EXPR The condition to assert.

Macro NOCH_ALLOC

#define NOCH_ALLOC(SIZE) malloc(SIZE)

Used to allocate memory in the Noch implementations.

Parameters

Name Description
SIZE The size in bytes to allocate.

Macro NOCH_REALLOC

#define NOCH_REALLOC(PTR, SIZE) realloc(SIZE)

Used to reallocate memory.

Parameters

Name Description
PTR Pointer to the previous allocated memory.
SIZE Size of the new memory to allocate.

Macro NOCH_FREE

#define NOCH_FREE(PTR) free(PTR)

Used to free memory.

Parameters

Name Description
PTR Pointer to the allocated memory to free.

Code rules

  • Always make sure the code does not give warnings and is valid in C++.

  • Never use integers for booleans, instead include stdbool.h. See the structure example for how to include stdbool.h.

  • Always use typedef for types.

Structure

Each Noch library has a .h file and a .c file. The .h contains declarations like a normal header file. See the template below.

example.h


						

The .c file contains the implementation of the library. See the template below.

example.c


						

Naming

  • Use snake_case for all variable, function, type, macro and file names.

  • Types have a _t suffix.

  • Macros are always upper case.

  • Variables, functions and types are prefixed with noch_ while macros are prefixed with NOCH_.

  • Implementation macros, functions etc. that are not supposed to be used by the library users have one more underscore added to the prefix, e.g. noch__my_func.

Functions

All functions must be defined with NOCH_DEF at the start, unless they are implementation-only functions that are not supposed to be used by the library users. In that case, the function must be defined as static. These functions are also only defined in the .c file.

example.c


						

If there is a structure and a function that returns a new instance of it, the function must be prefixed with the name of the structure type, excluding the _t suffix, like so:

example.h


						

The same applies if there is a function that in an object oriented language would be a method of the class (so takes a pointer to the structure and works with it, for example with the vec2_t structure it could be float noch_vec2_mag(vec2_t *vec2) for the magnitude of the vector).

Comments

The implementation code should be explained in comments, but only in parts that are not obvious. Always use C-style comments (/* */), not C++ ones (//)

Pre-processor

Pre-processor indentation should go after the hash:

Example


						

Formatting

  • Always use tab indentation with the width of 4 spaces.

  • Do not put { on a new line.

  • Lines are limited to 100 characters max (indentation counts as 4 characters).

  • If a line exceeds this limit and its caused by a long function/type name, consider making the name shorter, but not too short. If that is not possible, wrap the line.

  • When declaring pointer variables, attach the asterisk to the name, not type: int *a.

  • When casting, to a pointer, attach the asterisk to the type: (int*)x.

Line wrapping example