APIΒΆ

The Application Programming Interface describes how other code can use the code provided by the libraries contained in this project.

🧰 util¢

The util library is a simple set of miscellaneous functions to help write your code. None of the code is particularly clever or fancy, but will hopefully save you some time getting started.

The util library is built as a static library and can be linked into your code using the following CMake snippet.

target_link_libraries(<target> PUBLIC util)

cli.hΒΆ

Command line interface.

Enums

enum cli_rcΒΆ

Return codes for the cli_* family of functions.

Values:

enumerator CLI_RC_OKΒΆ

Success :)

enumerator CLI_RC_INVALID_VALUEΒΆ

An argument’s value cannot be parsed.

enumerator CLI_RC_UNSUPPORTED_ARGUMENTΒΆ

An argument is unexpected.

enumerator CLI_RC_MISSING_REQUIRED_ARGUMENTSΒΆ

The CLI was provided fewer arguments than required.

enumerator CLI_RC_MISSING_ARGUMENT_VALUEΒΆ

An optional argument requires a value that was not provided.

enum cli_actionΒΆ

The various actions the CLI library can take when it finds an argument.

Values:

enumerator PRINT_VERSIONΒΆ

Print the project’s version to stdout and exit.

enumerator PARSE_FLAGΒΆ

Set a bool to true if the argument is found.

enumerator PARSE_BOOLΒΆ

Parse the value of the argument into a bool.

enumerator PARSE_INT32ΒΆ

Parse the value of the argument into a int32_t.

enumerator PARSE_UINT32ΒΆ

Parse the value of the argument into a uint32_t.

enumerator PARSE_STRINGΒΆ

Parse the value of the argument into a char *.

Functions

void cli_parse(struct cli *cli, int argc, char *argv[])ΒΆ

Parse the arguments supplied to the application on the command line.

Parameters
  • cli – The cli object that defines the supported arguments.

  • argc – The length of the argv array.

  • argv – An array of strings representing the arguments and their values.

struct cli_argΒΆ
#include <cli.h>

A command line interface argument.

Public Members

char *long_nameΒΆ

The full name of the argument. Should start with -- to be considered optional. Can be NULL if short_name is not NULL.

char *short_nameΒΆ

The short name of the argument. Should start with - to be considered optional. Can be NULL if long_name is not NULL.

enum cli_action actionΒΆ

The action that should be taken when parsing this argument.

void *dataΒΆ

A pointer to the variable that should hold the value after the argument has been successfully parsed. Can be NULL if the action being taken isn’t to write a value to variable.

size_t data_sizeΒΆ

The size of the variable that data points to, in bytes.

char *descriptionΒΆ

A string that explains to the user what the argument does. Shown in help text. No description will be shown if NULL.

struct cliΒΆ
#include <cli.h>

Describe the command line interface.

Public Members

char *nameΒΆ

The name of the application. Shown in usage and help text. argv[0] will be printed if it’s NULL.

char *descriptionΒΆ

A description of the application. Shown in help text. Nothing will be printed if it’s NULL.

struct cli_arg *argsΒΆ

An array of cli_args that represent all the arguments the application supports.

size_t sizeΒΆ

The length of the args array.

color.hΒΆ

Add ANSI color codes to terminal output.

Enums

enum ANSI_color_codesΒΆ

A widely-supported subset of the possible terminal colour codes.

Values:

enumerator WHITEΒΆ
enumerator BLACKΒΆ
enumerator REDΒΆ
enumerator GREENΒΆ
enumerator YELLOWΒΆ
enumerator BLUEΒΆ
enumerator PURPLEΒΆ
enumerator CYANΒΆ
enumerator LIGHT_GRAYΒΆ

Functions

void color_init()ΒΆ

Initialise the color_ family of functions.

By default color is enabled for terminals and disabled for any file for which isatty returns false.

The COLOR environment variable can be used to override this behaviour: when set to ON it will force color to be always enabled, and similarly when set to OFF color will always be disabled regardless of the type of file.

bool color_set(FILE *file, enum ANSI_color_codes color)ΒΆ

Write color to file so that any subsequent writes are coloured.

env.hΒΆ

Functions for accessing environment variables.

Enums

enum env_rcΒΆ

Return codes for the env_<name> family of functions.

Values:

enumerator ENV_RC_OKΒΆ

All good in da hood.

enumerator ENV_RC_NO_VARIABLEΒΆ

The environment variable does not exist.

enumerator ENV_RC_INVALID_VALUEΒΆ

The environment variable exists but has a value that could not be parsed.

Functions

bool env_has(char const *name)ΒΆ

Return true if the environment variable name is defined.

enum env_rc env_get_bool(char const *name, bool *result)ΒΆ

Read an environment variable and convert its value to a boolean.

If name is not found then result will not be set and an error code will be returned.

If name is found then result will be set to:

  • true if the value is one of: 1, on, true.

  • false if the value is one of: 0, off, false.

Otherwise an error code will be returned.

Note that the comparisons are not case sensitive.

Parameters
  • name – The name of the environment variable.

  • result – The address of the memory to store the converted boolean value.

Returns

One of the following codes describing what the function did:

  • ENV_RC_OK: The environment variable name was found, converted to a boolean and written to address pointed to by result.

  • ENV_RC_NO_VARIABLE: If the environment variable does not exist.

  • ENV_RC_INVALID_VALUE: If the value could not be converted to a bool.

enum env_rc env_get_enum(char const *name, int *result, char const *enum_names[], size_t enum_names_size)ΒΆ

Read an environment variable and convert its value to an enum.

Example usage:

#include "util/env.h"
enum log_level { INFO, WARNING, ERROR };
char const * log_level_names[] = { "INFO", "WARNING", "ERROR" };
enum log_level level;
switch(env_get_enum("LOG_LEVEL", &level, log_level_names, 3))
{
    case ENV_RC_OK: return level;
    case ENV_RC_NO_VARIABLE: return INFO; // default value
    case ENV_RC_INVALID_VALUE: exit(EXIT_FAILURE);
}

Parameters
  • name – The name of the environment variable.

  • result – The enum to write the result too.

  • enum_names – List of names of the enum fields in value order. If the enum is not contiguous enum_names can be padded with NULLs to bridge the gap.

  • enum_names_size – The number of items in enum_names.

Returns

One of the following codes describing what the function did:

  • ENV_RC_OK: The environment variable name was found, converted to an enum value and written to address pointed to by result.

  • ENV_RC_NO_VARIABLE: If the environment variable does not exist.

  • ENV_RC_INVALID_VALUE: If the value of the environment variable was not found in enum_names.

log.hΒΆ

Logging functions.

Defines

log(level, ...)ΒΆ

Write a message to stdout or standard error.

fatal(...)ΒΆ

Call log() with FATAL level.

error(...)ΒΆ

Call log() with ERROR level.

warning(...)ΒΆ

Call log() with WARNING level.

success(...)ΒΆ

Call log() with SUCCESS level.

info(...)ΒΆ

Call log() with INFO level.

debug(...)ΒΆ

Call log() with DEBUG level.

Enums

enum log_levelΒΆ

The various severities of messages this logger supports.

Values:

enumerator NONEΒΆ

Disable all logging.

enumerator FATALΒΆ

Log messages before terminating the application.

enumerator ERRORΒΆ

Log errors from the application.

enumerator WARNINGΒΆ

Log warnings to the user.

enumerator SUCCESSΒΆ

Log successful operations.

enumerator INFOΒΆ

Log helpful information for the user.

enumerator DEBUGΒΆ

Log debug information for the developer.

Functions

const char *log_level_to_string(enum log_level level)ΒΆ

Return the name of the log level.

enum log_level string_to_log_level(const char *string)ΒΆ

Return the log level given the name. Return INT_MAX if no level exists for the given name.

enum ANSI_color_codes log_level_to_color(enum log_level level)ΒΆ

Return the ANSI color code used to print messages at log level.

void log_init()ΒΆ

Initialise the global log level.

This sets the application log level based on the LOG_LEVEL environment variable. If the LOG_LEVEL environment variable does not exist then the default log level is used.

Variables

enum log_level global_log_levelΒΆ

Global log level. Defaults to INFO.

string.hΒΆ

Utilities for working with strings.

Defines

string_literal(__s__)ΒΆ

Create a shallow copy of the string literal __s__.

string_join(result, ...)ΒΆ

Concatenate a variable number of string objects and store the result in result.

Typedefs

typedef struct string str_tΒΆ

Alias struct string to something much shorter.

Functions

void string_make(struct string *string, size_t size)ΒΆ

Allocate a new string and store the result in string.

If allocation fails the data member of string will be set to NULL and the size member will be set to 0.

When the string is no longer needed it should be passed to the string_free() function.

void string_copy(struct string *string, struct string *to_copy)ΒΆ

Create a copy of to_copy in string.

void string_copy_cstr(struct string *string, char const *to_copy)ΒΆ

Create a copy of to_copy in string.

void string_view(struct string *string, struct string *to_view)ΒΆ

Create a shallow copy of to_view in string.

void string_view_cstr_size(struct string *string, char *to_view, size_t size)ΒΆ

Create a shallow copy of [to_view,to_view+size) in string.

void string_view_cstr(struct string *string, char *to_view)ΒΆ

Create a shallow copy of to_view in string.

void string_free(struct string *string)ΒΆ

De-allocate memory from string.

bool string_is_same(struct string const *string, struct string const *other)ΒΆ

Return true if string and other reference the same memory.

bool string_is_equal(struct string const *string, struct string const *other)ΒΆ

Return true if the contents of string and other is the same.

bool string_is_equal_cstr(struct string const *string, char const *other)ΒΆ

Return true if the contents of string and other is the same.

bool string_starts_with_cstr(struct string const *string, char const *prefix)ΒΆ

Return true if string starts with prefix.

bool string_starts_with(struct string const *string, struct string const *prefix)ΒΆ

Return true if string starts with prefix.

bool string_end_with_cstr(struct string const *string, char const *suffix)ΒΆ

Return true if string ends with suffix.

bool string_ends_with(struct string const *string, struct string const *suffix)ΒΆ

Return true if string ends with suffix.

void string_join_array(struct string *result, struct string const *strings, size_t count)ΒΆ

Concatenate [strings, strings + count) and store the result in result.

Note

result must be deallocated by calling free .

void string_copy_slice(struct string *string, struct string *to_slice, size_t from, size_t to)ΒΆ

Copy to_slice[from, to) into string.

Note

string must be deallocated by calling string_free().

void string_view_slice(struct string *string, struct string *to_slice, size_t from, size_t to)ΒΆ

View to_slice[from, to) from string.

size_t string_copy_split(struct string **output, struct string const *to_split, char pivot)ΒΆ

Split the contents of to_split about pivot and store the pieces in output.

Note

output must be deallocated by calling free .

Parameters
  • output – The resulting pieces from the split.

  • to_split – The string to split into pieces.

  • pivot – The character to split about.

Returns

The number of strings stored in output.

size_t string_view_split(struct string **output, struct string const *to_split, char pivot)ΒΆ

Split the contents of to_split about pivot and store references to the pieces in output.

Note

output must be deallocated by calling free .

Parameters
  • output – The resulting pieces from the split.

  • to_split – The string to split into pieces.

  • pivot – The character to split about.

Returns

The number of strings stored in output.

struct stringΒΆ
#include <string.h>

A string that also stores its size.

Public Members

char *dataΒΆ

A pointer to the start of the string.

size_t sizeΒΆ

The length of the string in bytes.

timespec.hΒΆ

Utilities for working with timespecs.

Functions

struct timespec timespec_null()ΒΆ

Return a timespec with zero seconds and zero nanoseconds.

void timespec_iadd(struct timespec *lhs, struct timespec const *rhs)ΒΆ

Add rhs to lhs in-place.

void timespec_isub(struct timespec *lhs, struct timespec const *rhs)ΒΆ

Subtract rhs from lhs in-place.

void timespec_imul(struct timespec *lhs, struct timespec *rhs)ΒΆ

Multiply lhs by rhs in-place.

void timespec_idiv(struct timespec *lhs, long divisor)ΒΆ

Divide lhs by rhs in-place.

void timespec_duration(struct timespec *duration, struct timespec const *start, struct timespec const *stop)ΒΆ

Calculate the difference between start and stop and store the result in duration.

bool timespec_is_equal(const struct timespec *lhs, const struct timespec *rhs)ΒΆ

Return true if lhs is equal to rhs and return false otherwise.

bool timespec_is_less_than(const struct timespec *lhs, const struct timespec *rhs)ΒΆ

Return true if lhs is less than rhs and return false otherwise.

int timespec_compare(void const *lhs, void const *rhs)ΒΆ

Compare two timespecs.

Returns

An integer representing the result of the comparison:

  • -1 If lhs is less than rhs

  • 0 If lhs is equal to rhs

  • 1 If lhs is greather than rhs

double timespec_to_double_s(struct timespec *t)ΒΆ

Convert t to a double in units of seconds.

double timespec_to_double_ns(struct timespec *t)ΒΆ

Convert t to a double in units of nanoseconds.

struct timespec timespec_from_double_s(double d)ΒΆ

Convert d assuming its in units of seconds to a timespec.

struct timespec timespec_from_double_ns(double d)ΒΆ

Convert d assuming its in units of nanoseconds to a timespec.

util.hΒΆ

Defines

UNUSED(variable)ΒΆ

Mark variable as unused to stop compiler warnings.

ARRAY_SIZE(array)ΒΆ

Return the size of array (do not pass this a pointer!).

LIKELY(condition)ΒΆ

Tell the compiler condition is likely to be true.

UNLIKELY(condition)ΒΆ

Tell the compiler condition is unlikely to be true.

STR(expression)ΒΆ

Convert expression to a string literal.

ALWAYS_ASSERT(expression, message)ΒΆ

Log message and exit the program if expression evaluates to false.

ASSERT(expression, message)ΒΆ

Assert with a message if and only if NDEBUG is not defined.

πŸ§ͺ testΒΆ

The test_ library helps write unit test and benchmarks.

To link your code to it use:

target_link_libraries(<target> PUBLIC test_)

Note

The library is called test_ (with the underscore suffix) because CTest reserves the test target for itself.

benchmark.hΒΆ

A small and simple micro-benchmark library for benchmarking functions.

Defines

BENCH_WITH_NAME(__function__, __name__)ΒΆ

Benchmark __function__ and use __name__ to identify it in the print out.

BENCH(__function__)ΒΆ

Benchmark __function__ and print out the results.

Functions

void benchmark_init(const char *name)ΒΆ

Print out a table header and overhead measurement for the benchmarks.

void benchmark_print_results(struct BenchmarkResults *results)ΒΆ

Write results to stdout.

struct BenchmarkResults benchmark(void (*function)(void))ΒΆ

Benchmark function.

This measures the time to execute function and returns some summary statistics of the measurements.

struct BenchmarkResultsΒΆ
#include <benchmark.h>

Store summary statistics for a benchmark.

Public Members

const char *nameΒΆ

The name of the benchmark suite.

struct timespec minimumΒΆ

The smallest time it executed in.

struct timespec maximumΒΆ

The greatest time the function took.

struct timespec meanΒΆ

The average time of every function call.

struct timespec stddevΒΆ

The standard deviation of all measurements.

struct timespec percentiles[5]ΒΆ

1%, 25%, 50% (median), 75%, 99% percentiles.

unit_test.hΒΆ

A very simple unit test framework.

Defines

CHECK(__EXPR__)ΒΆ

Exit if __EXPR__ evaluates to false.

CHECK_RAISES(expression, __signal__)ΒΆ

Exit if expression does not raise __signal__.

Warning

Do not execute this macro concurrently.