Skip to content

IAKOBVS/jstring

Repository files navigation

jstring

jstring is a C string library which aims to make string manipulation simple and efficient.

Features:

  • fixed string and regex substitution with backreferences: replacing all occurrences is O(n).
  • compatible with other string libraries: string functions take a pointer to string, size, and capacity.
  • string list: easily create a list of dynamic strings.
  • fast substring matching: for x86-64 and needles that fit in a simd vector, use an O(n) simd implementation of memmem. For longer needles, precompile memmem. Currently, musl's twoway memmem implementation is used.
  • path traversal: ftw() that can take arguments.
  • useful return values: string functions suffixed with *_p return a pointer to the end of the processed string (like stpcpy). You are likely going to need the length of the string you just modified so this will often save an unnecessary strlen.
  • reverse versions of standard string functions: memrchr(), strrstr(), strrspn(), strrcspn(), etc.
  • standard string functions for non-nul terminated strings: memspn(), memcspn(), mempbrk(), etc.
  • extensions to standard string functions: strnchr(), strcasestr_len().
  • string formatting: asprintf() which returns the size of allocation and vsprintfstrlenmax() which returns the maximum size of allocation needed to store the characters written by vsprintf including the nul terminator.
  • namespacing: the library will only use [Jj][Ss][Tt][Rr]_* prefixed identifiers.

Installation:

./build && sudo ./install

Usage:

#include <jstr/jstr.h>

The following headers will need to be explicitly included (as they rely on POSIX):

#include <jstr/jstr-io.h>
#include <jstr/jstr-regex.h>

Examples:

https://github.com/IAKOBVS/find-and-replace

Disclaimer:

You must zero-initialize a jstr_ty string.

jstr_ty j = JSTR_INIT;

jstr_tolower() and jstr_toupper() will not handle EOF correctly. The tolower of EOF may not equal EOF.

Do not pass a string with embedded NULs to a function that takes a char * parameter. char * implies no embedded NULs. Use ones which takes a void *.

Configuration:

You can customize the library by defining certain macros in jstr-config.h before including any header. For example:

#define JSTR_USE_UNLOCKED_IO 1
#include <jstr/jstr.h>

Error handling:

A negative number is returned as error. The programmer is expected to check the return value and handle the error.

When a memory error is encountered, the user is expected to free all the related resources. Use jstr_err() to print the error message or jstr_errdie() to also exit. When debugging, you may want to define JSTR_PANIC as 1 to automatically call jstr_errdie() on errors.

For jstr-regex.h, jstr_re_rm*(), jstr_re_rplc*() will return a negative number indicating the negated value of the regex error code. To print an error message, pass the negation of the returned error code. This is done so that we can utilize the return value of the function both as the number of replacements done or as error values.

Naming conventions

Functions or macros:

  • *_mem*(): the string need not be nul-terminated.
  • *_len(): take the length of the string.
  • *str*_len(): the string passed to this function must be nul-termimated. The size parameter is only used to potentially save a strlen().
  • *stp*(), *_p(), *P(): return a pointer to the end of the string.
  • *_unsafe(): assume that there be enough space in the string: the string will not be grown.
  • *_from(): operate starting from a specified index. The index passed by the user is assumed to be within bounds.
  • *_bref(): enable backreferences for the replacement string. \0 is interpreted as referring to the whole matched string.
  • *_at(): return an element of from an array type. When JSTR_DEBUG is defined as 1, do bounds checking at runtime.
  • *_chk*(): evaluate to true if the value passed is an error value.
  • *_err(): print an error message.
  • *_errdie(): print an error message and exit().
  • namespace__*(): internal functions.

Headers:

  • _*.h: internal headers.

Scripts:

  • build: generate functions.
  • test: run tests.
  • install: build and copy headers to /usr/local/include/jstr (requires sudo).
  • install-to: install to a specified directory.
  • uninstall: remove /usr/local/include/jstr (requires sudo).
  • clean: remove files generated by build.
  • update: update the repository and build.
  • fmt: format files.

Contributing:

Do not put blank lines inside a function. The perl script splits each block of code by blank lines. If you need to put blank lines, add a comment. For example:

void f()
{
	Some code...
	/* */
	Some other code...
}