/hlc

Higher-level C - A set of high(er) level C utilities

Primary LanguageCMIT LicenseMIT

hlc - high(er) level C utilities
================================

hlc is a collection of some nice, basic C utilities that can make your code a
little safer and easier to read. These are mostly header-only libraries that I
have collected through having written quite a bit of C.

C is notoriously difficult to get basic things completely right in unless you
know what you are doing. Hopefully, I know a little of what I am doing, as I
have written an equivalent of all these utilities several times for each
project. So, I thought I would collect them all together.

These do not replace the C standard library and should not be used everywhere,
but they are as portable as I can manage and tend to have few or no
dependencies. Most are in a single header file. More complicated utilities may
compile to a library or other object format, but, in general, these are
designed to just be dropped into your source tree.

How to use
----------

1. Grab the header file that looks of use to you
2. Copy it (with the licence comment included) into your source tree
3. #include it in your code having already #included any headers marked as
   dependencies in the doc comment

Table of Contents
-----------------

str/:    a portable and efficient Pascal-like strings implementation with
         associated utilities
utf.h:   a portable and simple wrapper around standard wide character functions
         for ease-of-use (should encourage people to actually support wide
         characters).
vect.h:  a safe, portable and TYPE-SAFE, C++-like vector implementation
slice.h: an abstraction over any dynamic container with a length and
         capacity, Go style. Automation of the age-old len, cap, realloc
         pattern.
buf.h:   macros for assistance when working with heap-allocated buffers. can be
         used as a minimal alternative to slice.h
sync.h:  (REQUIRES C11*) an implementation of a spinlock, mutex and atomic
         variables
chan.h:  (REQUIRES C11*) an implementation of a by-value CSP channel, Go style

--
* (REQUIRES C11): Any compiler which implements C11-style atomics is sufficient

Information
-----------

UTF-8:
~~~~~

Supported, but only in that most of the library routines carefully step around
interpreting the contents of a string.

Namespace pollution:
~~~~~~~~~~~~~~~~~~~~

hlc declares types under the <typename>_t namespace, which could cause clashes
if any already exist. Other than that, each utility only declares symbols under
the namespace of their purpose (strings: "str_", slices: "slc_"). Internal
symbols are prefixed with an underscore  (strings: "_str_", slices: "_slc_").
hlc headers declare everything to be static and some to be inline, such that
only the current translation unit will be affected by the definitions. This is
by design, as anything else would make it impossible to use the library in
multiple translation units.

I/O Routines:
~~~~~~~~~~~~~

Some features that may be considered "basic" (such as returning a char * from
stdin) are deliberately omitted, as they are carry overs from other languages
and do not fit the design of C. Instead, for example, read input in known-sized
chunks and process it from there, rather than needlessly copying an unbounded
amount into your process memory space and processing it later. Obviously,
feature omissions happen so please do not be afraid to request an addition.

Errors from #include(s):
~~~~~~~~~~~~~~~~~~~~~~~~

Please read the doc comment for the header to check which standard library
headers it requires. Alternatively, define the macro HLC_AUTO_INCLUDE or the
same for the header's namespace (eg for strings: STR_AUTO_INCLUDE).

Minimum C version:
~~~~~~~~~~~~~~~~~~

Mostly C99, but some headers require C11 for various reasons which are made
clear in the table of contents and doc comments.

Influences
----------

hlc is heavily influenced by both the standard libraries of Go (https://go.dev/)
and Rust (https://www.rust-lang.org/).

It is also influenced by my own experiences of writing C programs and being
irritated by some specific issues posed.