summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile219
-rw-r--r--changelog.md13
-rw-r--r--docs/u8c_abrt.324
-rw-r--r--docs/u8c_col.333
-rw-r--r--docs/u8c_dbg.318
-rw-r--r--docs/u8c_dbgprint.323
-rw-r--r--docs/u8c_end.324
-rw-r--r--docs/u8c_errhandltyp.320
-rw-r--r--docs/u8c_errtyp.330
-rw-r--r--docs/u8c_fmt.318
-rw-r--r--docs/u8c_fmttyp.345
-rw-r--r--docs/u8c_geterr.319
-rw-r--r--docs/u8c_init.319
-rw-r--r--docs/u8c_isalnum.319
-rw-r--r--docs/u8c_isalpha.319
-rw-r--r--docs/u8c_iscntrl.319
-rw-r--r--docs/u8c_isdigit.319
-rw-r--r--docs/u8c_ispunct.319
-rw-r--r--docs/u8c_isspace.319
-rw-r--r--docs/u8c_isxdigit.319
-rw-r--r--docs/u8c_print.319
-rw-r--r--docs/u8c_println.319
-rw-r--r--docs/u8c_regerrhandl.322
-rw-r--r--docs/u8c_seterr.319
-rw-r--r--docs/u8c_setfmt.318
-rw-r--r--docs/u8c_thrdsafe.322
-rw-r--r--docs/u8c_u32alloc.319
-rw-r--r--docs/u8c_u32cat.319
-rw-r--r--docs/u8c_u32cmp.319
-rw-r--r--docs/u8c_u32cp.319
-rw-r--r--docs/u8c_u32fndchr.319
-rw-r--r--docs/u8c_u32fndpat.319
-rw-r--r--docs/u8c_u32free.318
-rw-r--r--docs/u8c_u32ins.319
-rw-r--r--docs/u8c_u32substr.319
-rw-r--r--docs/u8c_u32sz.319
-rw-r--r--docs/u8c_u8alloc.318
-rw-r--r--docs/u8c_u8dec.327
-rw-r--r--docs/u8c_u8enc.327
-rw-r--r--docs/u8c_u8free.317
-rw-r--r--docs/u8c_unimax.318
-rw-r--r--docs/u8c_ver.317
-rw-r--r--docs/u8c_vfmt.320
-rw-r--r--docs/u8c_vprint.320
-rw-r--r--include/u8c/end.h1
-rw-r--r--include/u8c/errhandltyp.h20
-rw-r--r--include/u8c/errtyp.h29
-rw-r--r--include/u8c/init.h1
-rw-r--r--include/u8c/regerrhandl.h23
-rw-r--r--include/u8c/seterr.h3
-rw-r--r--include/u8c/u32cmp.h1
-rw-r--r--include/u8c/u32cp.h1
-rw-r--r--include/u8c/u32fndchr.h1
-rw-r--r--include/u8c/u32ins.h23
-rw-r--r--include/u8c/ver.h2
-rw-r--r--src/u8c/dat.c2
-rw-r--r--src/u8c/dattyp.h11
-rw-r--r--src/u8c/geterr.c2
-rw-r--r--src/u8c/init.c6
-rw-r--r--src/u8c/println.c3
-rw-r--r--src/u8c/regerrhandl.c41
-rw-r--r--src/u8c/seterr.c14
-rw-r--r--src/u8c/u32alloc.c7
-rw-r--r--src/u8c/u32cat.c8
-rw-r--r--src/u8c/u32cmp.c3
-rw-r--r--src/u8c/u32fndchr.c12
-rw-r--r--src/u8c/u32free.c2
-rw-r--r--src/u8c/u32ins.c49
-rw-r--r--src/u8c/u32substr.c4
-rw-r--r--src/u8c/u8alloc.c7
-rw-r--r--src/u8c/u8dec.c5
-rw-r--r--src/u8c/u8enc.c6
-rw-r--r--src/u8c/vprint.c3
-rw-r--r--test.c42
74 files changed, 1311 insertions, 131 deletions
diff --git a/Makefile b/Makefile
index 7cfd1c9..42cd61c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
CC = clang
-CFLAGS = -std=c17 -Wall -Wextra -pedantic-errors -Iinclude -march=native -mtune=native -fPIC
+CFLAGS = -std=c17 -Wall -Wextra -Wmissing-prototypes -Wpadded -pedantic-errors -Iinclude -fPIC
ifneq ($(thrdsafe),0)
CFLAGS += -Du8c_bethrdsafe
endif
@@ -10,102 +10,151 @@ CFLAGS += -O3 -DNDEBUG
endif
LDFLAGS = -shared -lpthread
HDRS = \
- include/u8c/SIZE_C.h \
- include/u8c/abrt.h \
- include/u8c/col.h \
- include/u8c/dbg.h \
- include/u8c/dbgprint.h \
- include/u8c/end.h \
- include/u8c/fmt.h \
- include/u8c/fmttyp.h \
- include/u8c/geterr.h \
- include/u8c/init.h \
- include/u8c/isalnum.h \
- include/u8c/isalpha.h \
- include/u8c/iscntrl.h \
- include/u8c/isdigit.h \
- include/u8c/ispunct.h \
- include/u8c/isspace.h \
- include/u8c/isxdigit.h \
- include/u8c/print.h \
- include/u8c/println.h \
- include/u8c/seterr.h \
- include/u8c/setfmt.h \
- include/u8c/thrdsafe.h \
- include/u8c/u32alloc.h \
- include/u8c/u32cat.h \
- include/u8c/u32cmp.h \
- include/u8c/u32cp.h \
- include/u8c/u32fndchr.h \
- include/u8c/u32fndpat.h \
- include/u8c/u32free.h \
- include/u8c/u32substr.h \
- include/u8c/u32sz.h \
- include/u8c/u8alloc.h \
- include/u8c/u8dec.h \
- include/u8c/u8enc.h \
- include/u8c/u8free.h \
- include/u8c/unimax.h \
- include/u8c/ver.h \
- include/u8c/vfmt.h \
+ include/u8c/SIZE_C.h \
+ include/u8c/abrt.h \
+ include/u8c/col.h \
+ include/u8c/dbg.h \
+ include/u8c/dbgprint.h \
+ include/u8c/end.h \
+ include/u8c/errhandltyp.h \
+ include/u8c/errtyp.h \
+ include/u8c/fmt.h \
+ include/u8c/fmttyp.h \
+ include/u8c/geterr.h \
+ include/u8c/init.h \
+ include/u8c/isalnum.h \
+ include/u8c/isalpha.h \
+ include/u8c/iscntrl.h \
+ include/u8c/isdigit.h \
+ include/u8c/ispunct.h \
+ include/u8c/isspace.h \
+ include/u8c/isxdigit.h \
+ include/u8c/print.h \
+ include/u8c/println.h \
+ include/u8c/regerrhandl.h \
+ include/u8c/seterr.h \
+ include/u8c/setfmt.h \
+ include/u8c/thrdsafe.h \
+ include/u8c/u32alloc.h \
+ include/u8c/u32cat.h \
+ include/u8c/u32cmp.h \
+ include/u8c/u32cp.h \
+ include/u8c/u32fndchr.h \
+ include/u8c/u32fndpat.h \
+ include/u8c/u32free.h \
+ include/u8c/u32ins.h \
+ include/u8c/u32substr.h \
+ include/u8c/u32sz.h \
+ include/u8c/u8alloc.h \
+ include/u8c/u8dec.h \
+ include/u8c/u8enc.h \
+ include/u8c/u8free.h \
+ include/u8c/unimax.h \
+ include/u8c/ver.h \
+ include/u8c/vfmt.h \
include/u8c/vprint.h
HDRS_PRIV = \
- src/u8c/dat.h \
+ src/u8c/dat.h \
src/u8c/dattyp.h
SRCS = \
- src/u8c/abrt.c \
- src/u8c/dat.c \
- src/u8c/debug.c \
- src/u8c/end.c \
- src/u8c/fmt.c \
- src/u8c/geterr.c \
- src/u8c/init.c \
- src/u8c/isalnum.c \
- src/u8c/isalpha.c \
- src/u8c/iscntrl.c \
- src/u8c/isdigit.c \
- src/u8c/isspace.c \
- src/u8c/ispunct.c \
- src/u8c/isxdigit.c \
- src/u8c/print.c \
- src/u8c/println.c \
- src/u8c/seterr.c \
- src/u8c/setfmt.c \
- src/u8c/thrdsafe.c \
- src/u8c/u32alloc.c \
- src/u8c/u32cat.c \
- src/u8c/u32cmp.c \
- src/u8c/u32cp.c \
- src/u8c/u32fndchr.c \
- src/u8c/u32fndpat.c \
- src/u8c/u32free.c \
- src/u8c/u32substr.c \
- src/u8c/u32sz.c \
- src/u8c/u8alloc.c \
- src/u8c/u8dec.c \
- src/u8c/u8enc.c \
- src/u8c/u8free.c \
- src/u8c/vfmt.c \
+ src/u8c/abrt.c \
+ src/u8c/dat.c \
+ src/u8c/debug.c \
+ src/u8c/end.c \
+ src/u8c/fmt.c \
+ src/u8c/geterr.c \
+ src/u8c/init.c \
+ src/u8c/isalnum.c \
+ src/u8c/isalpha.c \
+ src/u8c/iscntrl.c \
+ src/u8c/isdigit.c \
+ src/u8c/isspace.c \
+ src/u8c/ispunct.c \
+ src/u8c/isxdigit.c \
+ src/u8c/print.c \
+ src/u8c/println.c \
+ src/u8c/regerrhandl.c \
+ src/u8c/seterr.c \
+ src/u8c/setfmt.c \
+ src/u8c/thrdsafe.c \
+ src/u8c/u32alloc.c \
+ src/u8c/u32cat.c \
+ src/u8c/u32cmp.c \
+ src/u8c/u32cp.c \
+ src/u8c/u32fndchr.c \
+ src/u8c/u32fndpat.c \
+ src/u8c/u32free.c \
+ src/u8c/u32ins.c \
+ src/u8c/u32substr.c \
+ src/u8c/u32sz.c \
+ src/u8c/u8alloc.c \
+ src/u8c/u8dec.c \
+ src/u8c/u8enc.c \
+ src/u8c/u8free.c \
+ src/u8c/vfmt.c \
src/u8c/vprint.c
OBJS = $(SRCS:.c=.o)
LIB = libu8c.so
$(LIB): $(OBJS)
$(CC) $(LDFLAGS) $^ -o $@
$(OBJS): $(HDRS) $(HDRS_PRIV)
-.PHONY: clean install purge runtest uninstall
+DOCS = \
+ docs/u8c_abrt.3.zst \
+ docs/u8c_col.3.zst \
+ docs/u8c_dbg.3.zst \
+ docs/u8c_dbgprint.3.zst \
+ docs/u8c_end.3.zst \
+ docs/u8c_errhandltyp.3.zst \
+ docs/u8c_errtyp.3.zst \
+ docs/u8c_fmt.3.zst \
+ docs/u8c_fmttyp.3.zst \
+ docs/u8c_geterr.3.zst \
+ docs/u8c_init.3.zst \
+ docs/u8c_isalnum.3.zst \
+ docs/u8c_isalpha.3.zst \
+ docs/u8c_iscntrl.3.zst \
+ docs/u8c_digit.3.zst \
+ docs/u8c_ispunct.3.zst \
+ docs/u8c_isspace.3.zst \
+ docs/u8c_isxdigit.3.zst \
+ docs/u8c_print.3.zst \
+ docs/u8c_println.3.zst \
+ docs/u8c_regerrhandl.3.zst \
+ docs/u8c_seterr.3.zst \
+ docs/u8c_setfmt.3.zst \
+ docs/u8c_thrdsafe.3.zst \
+ docs/u8c_u8alloc.3.zst \
+ docs/u8c_u8dec.3.zst \
+ docs/u8c_u8enc.3.zst \
+ docs/u8c_u8free.3.zst \
+ docs/u8c_u32alloc.3.zst \
+ docs/u8c_u32cat.3.zst \
+ docs/u8c_u32cmp.3.zst \
+ docs/u8c_u32cp.3.zst \
+ docs/u8c_u32fndchr.3.zst \
+ docs/u8c_u32fndpat.3.zst \
+ docs/u8c_u32free.3.zst \
+ docs/u8c_u32ins.3.zst \
+ docs/u8c_u32substr.3.zst \
+ docs/u8c_u32sz.3.zst \
+ docs/u8c_unimax.3.zst \
+ docs/u8c_ver.3.zst \
+ docs/u8c_vfmt.3.zst \
+ docs/u8c_vprint.3.zst
+$(DOCS):
+ zstd -f $(DOCS:.zst=)
+test: $(LIB) test.c
+ $(CC) -std=c17 -Wall -Wextra -Wpedantic -Iinclude -O3 -g -L. -lu8c -o $@ [email protected]
+.PHONY: clean docs install runtest
clean:
- rm --force $(OBJS)
-install: $(LIB)
+ rm --force test $(DOCS) $(LIB) $(OBJS)
+docs: $(DOCS)
+install: $(LIB) $(DOCS)
mkdir --parents $(DESTDIR)/include/u8c
mkdir --parents $(DESTDIR)/lib
- install --mode=444 $(HDRS) $(DESTDIR)/include/u8c
- install --mode=555 $(LIB) $(DESTDIR)/lib
-purge:
- rm --force test txttolit $(LIB) $(OBJS)
+ mkdir --parents $(DESTDIR)/share/man/man3
+ install --mode=444 --verbose $(DOCS) $(DESTDIR)/share/man/man3
+ install --mode=444 --verbose $(HDRS) $(DESTDIR)/include/u8c
+ install --mode=555 --verbose $(LIB) $(DESTDIR)/lib
runtest: test
export LD_LIBRARY_PATH=$(CURDIR) && ./$^
-test: $(LIB) test.c
- $(CC) -std=c17 -Wall -Wextra -Wpedantic -Iinclude -march=native -mtune=native -O3 -g -L. -lu8c -o $@ [email protected]
-uninstall:
- rm --force --recursive $(DESTDIR)/include/u8c/
- rm --force --recursive $(DESTDIR)/lib/$(LIB)
diff --git a/changelog.md b/changelog.md
index 3674efa..90a18e3 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,16 @@
+# 19
+
+* Fix error when compiling with GCC: *src/u8c/dat.c:22:29: error: initializer element is not constant [-Wpedantic]*.
+* Improve error handling:
+ * Add enumeration type for error types; `u8c_errtyp`.
+ * Add function for registering error handlers; `u8c_regerrhandl` (see `test.c`).
+* Add function for inserting UTF-32 strings into UTF-32 strings; `u8c_u32ins`.
+* Enable more warnings.
+* Add man pages.
+* Fix `u8c_u32cat` skipping the last character in `lstr`.
+* Remove the `uninstall` target (it was deemed to unsafe).
+* Add *Zstandard* as a dependency.
+
# 18
* Update `.gitignore`.
diff --git a/docs/u8c_abrt.3 b/docs/u8c_abrt.3
new file mode 100644
index 0000000..0445701
--- /dev/null
+++ b/docs/u8c_abrt.3
@@ -0,0 +1,24 @@
+.TH "u8c_abrt" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_abrt - Abort - Abort program with diagnostic information.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h
+# include <stdnoreturn.h>
+# include <uchar.h>
+extern noreturn bool u8c_abrt(char const * const fl,long long const ln,char const * const fn,char const * const why);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The function \f[B]u8c_abrt\f[R] aborts the program and prints diagnostic infiormation to \f[B]stderr\f[R].
+.PP
+\f[B]__FILE__\f[R] is to be passed at \f[B]fl\f[R], \f[B](long long)__LINE__\f[R] at \f[B]ln\f[B], and \f[B]__func__\f[R] at \f[B]fn\f[R]. A standard string (\f[B]char const *\f[R]) must be passed at \f[B]why\f[R], which explains the reason for aborting.
+.PP
+All arguments are printed, in the end followed by a timestamp representing the number of seconds passed since the current epoch (as returned by \f[B]time(NULL)\f[R]).
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_col.3 b/docs/u8c_col.3
new file mode 100644
index 0000000..b0fb658
--- /dev/null
+++ b/docs/u8c_col.3
@@ -0,0 +1,33 @@
+.TH "u8c_col" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_col - Colour - Set of macros expanding to hexadecimal colour value expressions.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdint.h>
+# define u8c_col_azure (UINT32_C(0x3DA9E1))
+# define u8c_col_ash (UINT32_C(0xD2D2CC))
+# define u8c_col_black (UINT32_C(0x444747))
+# define u8c_col_blue (UINT32_C(0x3D3DE1))
+# define u8c_col_chartreuse (UINT32_C(0xA9E13D))
+# define u8c_col_cyan (UINT32_C(0x3DE1E1))
+# define u8c_col_green (UINT32_C(0x3ED13D))
+# define u8c_col_magenta (UINT32_C(0xE13DE1))
+# define u8c_col_mint (UINT32_C(0x3DE1A9))
+# define u8c_col_orange (UINT32_C(0xE1A93D))
+# define u8c_col_red (UINT32_C(0xE13D3D))
+# define u8c_col_rose (UINT32_C(0xE13DA9))
+# define u8c_col_silver (UINT32_C(0x9CA1A1))
+# define u8c_col_violet (UINT32_C(0xA93dE1))
+# define u8c_col_white (UINT32_C(0xF8F8F1))
+# define u8c_col_yellow (UINT32_C(0xE1E13D))
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The macro set \f[B]u8c_col\f[R] contains sixteen macros expanding to hexadecimal colour value expressions of type \f[B]uint_least32_t\f[R].
+.SH VERSION
+.PP
+u8c 2
diff --git a/docs/u8c_dbg.3 b/docs/u8c_dbg.3
new file mode 100644
index 0000000..d1f95eb
--- /dev/null
+++ b/docs/u8c_dbg.3
@@ -0,0 +1,18 @@
+.TH "u8c_dbg" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_dbg - Debug - Whether or not the library is in debug mode.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+extern bool const u8c_dbg;
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The constant \f[B]u8c_dbg\f[R] has value \f[B]false\f[R] if u8c has been compiled with debugging disabled, otherwise \f[B]true\f[R].
+.SH VERSION
+.PP
+u8c 0 (as \f[B]u8c_debug\f[R]), u8c 16
diff --git a/docs/u8c_dbgprint.3 b/docs/u8c_dbgprint.3
new file mode 100644
index 0000000..e7c609f
--- /dev/null
+++ b/docs/u8c_dbgprint.3
@@ -0,0 +1,23 @@
+.TH "u8c_dbgprint" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_dbgprint - Debug print - Print line if debug mode is enabled.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# if defined(NDEBUG)
+# define u8c_dbgprint(...) ((void)0x0)
+# else
+# include <u8c/println.h>
+# include <stdio.h>
+# define u8c_dbgprint(...) u8c_println(stderr,__VA_ARGS__)
+# endif
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The function-like macro \f[B]u8c_dbgprint\f[R] passes it\[cq]s input to \f[B]u8c_println\f[R] (if the \f[B]NDEBUG\f[R] macro is defined, nothing is done).
+.SH VERSION
+.PP
+u8c 0
diff --git a/docs/u8c_end.3 b/docs/u8c_end.3
new file mode 100644
index 0000000..bf8c81e
--- /dev/null
+++ b/docs/u8c_end.3
@@ -0,0 +1,24 @@
+.TH "u8c_end" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_end - End - Finalise u8c and clean up.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+extern bool u8c_end(void);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The function \f[B]u8c_end\f[R] ends the current u8c session.
+.PP
+If \f[B]u8c_end\f[R] is called before \f[B]u8c_init\f[R], \f[B]false\f[R] is returned, and nothing has happened.
+.PP
+If it is called after it has already been called, unless \f[B]u8c_init\f[R] has been called in the meantime, \f[B]false\f[R] is returned, and nothing has happened.
+.PP
+Even if \f[B]u8c_thrdsafe\f[R] evaluates to \f[B]true\f[R], this function is never thread-safe.
+.SH VERSION
+.PP
+u8c 2
diff --git a/docs/u8c_errhandltyp.3 b/docs/u8c_errhandltyp.3
new file mode 100644
index 0000000..ac7f8e2
--- /dev/null
+++ b/docs/u8c_errhandltyp.3
@@ -0,0 +1,20 @@
+.TH "u8c_errhandltyp" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_errhandltyp - Error handler type - Type to be used for error handlers passerd to \f[B]u8c_regerrhandl\f[R].
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <u8c/errtyp.h>
+typedef void (* u8c_errhandltyp)(enum u8c_errtyp);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The type definition \f[B]u8c_errhandltyp\f[R] is for convenience.
+.PP
+It is to be the type of the error handler accepted by \f[B]u8c_regerrhandl\f[R].
+.SH VERSION
+.PP
+u8c 19
diff --git a/docs/u8c_errtyp.3 b/docs/u8c_errtyp.3
new file mode 100644
index 0000000..cd0a282
--- /dev/null
+++ b/docs/u8c_errtyp.3
@@ -0,0 +1,30 @@
+.TH "u8c_errtyp" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_errtyp - Error type - Enumeration for specifying the type of error.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+enum u8c_errtyp {
+ u8c_errtyp_badalloc,
+ u8c_errtyp_badio,
+ u8c_errtyp_u32oor,
+ u8c_errtyp_u8oor,
+ u8c_errtyp_deferr,
+ u8c_errtyp_untermin,
+ u8c_errtyp_maxerrtyp,
+ u8c_errtyp_all,
+};
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The enumeration \f[B]u8c_errtyp\f[R] contains the various types of error to be used in u8c.
+.PP
+The member \f[B]u8c_errtyp_maxerrtyp\f[R] must \f[I]NEVER\f[R] be passed to any u8c function.
+.PP
+The member \f[B]u8c_errtyp_all\f[R] is to be passed to \f[B]u8c_regerrhandl\f[R] only.
+.SH VERSION
+.PP
+u8c 19
diff --git a/docs/u8c_fmt.3 b/docs/u8c_fmt.3
new file mode 100644
index 0000000..cbb823b
--- /dev/null
+++ b/docs/u8c_fmt.3
@@ -0,0 +1,18 @@
+.TH "u8c_fmt" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_fmt - Format - Format UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_fmt(size_t * const outsz,char32_t const * * const out,char32_t const * const in,...);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 2
diff --git a/docs/u8c_fmttyp.3 b/docs/u8c_fmttyp.3
new file mode 100644
index 0000000..8cdea7c
--- /dev/null
+++ b/docs/u8c_fmttyp.3
@@ -0,0 +1,45 @@
+.TH "u8c_fmttyp" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_fmttyp - Format type - Format specifier to be used by \f[C]u8c_fmt\f[R] or \f[C]u8c_vfmt\f[R].
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+enum u8c_fmttyp {
+ u8c_fmttyp_bgcol,
+ u8c_fmttyp_bgcol0,
+ u8c_fmttyp_bool,
+ u8c_fmttyp_byt,
+ u8c_fmttyp_chr,
+ u8c_fmttyp_fgcol,
+ u8c_fmttyp_fgcol0,
+ u8c_fmttyp_int,
+ u8c_fmttyp_int16,
+ u8c_fmttyp_int32,
+ u8c_fmttyp_int64,
+ u8c_fmttyp_int8,
+ u8c_fmttyp_llong,
+ u8c_fmttyp_long,
+ u8c_fmttyp_sbyt,
+ u8c_fmttyp_shrt,
+ u8c_fmttyp_str,
+ u8c_fmttyp_sz,
+ u8c_fmttyp_tm,
+ u8c_fmttyp_ubyt,
+ u8c_fmttyp_uint,
+ u8c_fmttyp_uint16,
+ u8c_fmttyp_uint32,
+ u8c_fmttyp_uint64,
+ u8c_fmttyp_uint8,
+ u8c_fmttyp_ulong,
+ u8c_fmttyp_ullong,
+ u8c_fmttyp_ushrt,
+};
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 0
diff --git a/docs/u8c_geterr.3 b/docs/u8c_geterr.3
new file mode 100644
index 0000000..c74b25f
--- /dev/null
+++ b/docs/u8c_geterr.3
@@ -0,0 +1,19 @@
+.TH "u8c_geterr" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_geterr - Get error - Get last error set by \f[C]u8c_seterr\f[R].
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_geterr(size_t * const sz,char32_t const * * const out);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 2
diff --git a/docs/u8c_init.3 b/docs/u8c_init.3
new file mode 100644
index 0000000..0491a0b
--- /dev/null
+++ b/docs/u8c_init.3
@@ -0,0 +1,19 @@
+.TH "u8c_init" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_init - Initialise - Initialise and start an u8c session.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <u8c/errtyp.h>
+extern bool u8c_init(void);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+Even if \f[B]u8c_thrdsafe\f[R] evaluates to \f[B]true\f[R], this function is never thread-safe.
+.SH VERSION
+.PP
+u8c 2
diff --git a/docs/u8c_isalnum.3 b/docs/u8c_isalnum.3
new file mode 100644
index 0000000..c8f9dcc
--- /dev/null
+++ b/docs/u8c_isalnum.3
@@ -0,0 +1,19 @@
+.TH "u8c_isalnum" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_isalnum - Is alphanumeric - Check if a character is alphanumeric.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdint.h>
+# include <uchar.h>
+extern bool u8c_isalnum(uint_least8_t * const res,char32_t const chr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c X
diff --git a/docs/u8c_isalpha.3 b/docs/u8c_isalpha.3
new file mode 100644
index 0000000..c6cc372
--- /dev/null
+++ b/docs/u8c_isalpha.3
@@ -0,0 +1,19 @@
+.TH "u8c_isalpha" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_isalpha - Is alphabetic - Check if a character is alphabetic.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdint.h>
+# include <uchar.h>
+extern bool u8c_isalpha(uint_least8_t * const res,char32_t const chr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c X
diff --git a/docs/u8c_iscntrl.3 b/docs/u8c_iscntrl.3
new file mode 100644
index 0000000..1c27b82
--- /dev/null
+++ b/docs/u8c_iscntrl.3
@@ -0,0 +1,19 @@
+.TH "u8c_iscntrl" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_iscntrl - Is control - Check if a character is a control character.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdint.h>
+# include <uchar.h>
+extern bool u8c_iscntrl(uint_least8_t * const res,char32_t const chr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c X
diff --git a/docs/u8c_isdigit.3 b/docs/u8c_isdigit.3
new file mode 100644
index 0000000..6b3ec4a
--- /dev/null
+++ b/docs/u8c_isdigit.3
@@ -0,0 +1,19 @@
+.TH "u8c_isdigit" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_isdigit - Is digit - Check if a character is a dozenal digit.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdint.h>
+# include <uchar.h>
+extern bool u8c_isdigit(uint_least8_t * const res,char32_t const chr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c X
diff --git a/docs/u8c_ispunct.3 b/docs/u8c_ispunct.3
new file mode 100644
index 0000000..af607cb
--- /dev/null
+++ b/docs/u8c_ispunct.3
@@ -0,0 +1,19 @@
+.TH "u8c_ispunct" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_ispunct - Is punctuation - Check if a character is a punctuation mark.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdint.h>
+# include <uchar.h>
+extern bool u8c_ispunct(uint_least8_t * const res,char32_t const chr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c X
diff --git a/docs/u8c_isspace.3 b/docs/u8c_isspace.3
new file mode 100644
index 0000000..72ad3e1
--- /dev/null
+++ b/docs/u8c_isspace.3
@@ -0,0 +1,19 @@
+.TH "u8c_isspace" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_isspace - Is space - Check if a character is an whitespace.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdint.h>
+# include <uchar.h>
+extern bool u8c_isspace(uint_least8_t * const res,char32_t const chr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c X
diff --git a/docs/u8c_isxdigit.3 b/docs/u8c_isxdigit.3
new file mode 100644
index 0000000..66c7955
--- /dev/null
+++ b/docs/u8c_isxdigit.3
@@ -0,0 +1,19 @@
+.TH "u8c_isxdigit" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_isxdigit - Is hexadecimal digit - Check if a character is a hexadecimal digit.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdint.h>
+# include <uchar.h>
+extern bool u8c_isxdigit(uint_least8_t * const res,char32_t const chr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_print.3 b/docs/u8c_print.3
new file mode 100644
index 0000000..54a7466
--- /dev/null
+++ b/docs/u8c_print.3
@@ -0,0 +1,19 @@
+.TH "u8c_print" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_print - Print - Format UTF-32 and print it to file.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdio.h>
+# include <uchar.h>
+extern bool u8c_print(FILE * fp,char32_t const * const msg,...);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 2
diff --git a/docs/u8c_println.3 b/docs/u8c_println.3
new file mode 100644
index 0000000..72345a6
--- /dev/null
+++ b/docs/u8c_println.3
@@ -0,0 +1,19 @@
+.TH "u8c_println" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_println - Print line - Format UTF-32 and print it to file (followed by a new-line).
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdio.h>
+# include <uchar.h>
+extern bool u8c_println(FILE * fp,char32_t const * const msg,...);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 0 (as u8c_print), u8c 2
diff --git a/docs/u8c_regerrhandl.3 b/docs/u8c_regerrhandl.3
new file mode 100644
index 0000000..7b2f824
--- /dev/null
+++ b/docs/u8c_regerrhandl.3
@@ -0,0 +1,22 @@
+.TH "u8c_regerrhandl" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_regerrhandl - Register error handler - Register error handler function to be called by \f[B]u8c_seterr\f[R].
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <u8c/errhandltyp.h>
+# include <u8c/errtyp.h>
+extern bool u8c_regerrhandl(enum u8c_errtyp typ,u8c_errhandltyp errhandl);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+Registers an error handler to be called when an error of type \f[B]typ\f[R] is detected.
+.PP
+If \f[B]u8c_errtyp_all\f[R] is passed at \f[B]typ\f[R], the error handler is registered for all error types.
+.SH VERSION
+.PP
+u8c 19
diff --git a/docs/u8c_seterr.3 b/docs/u8c_seterr.3
new file mode 100644
index 0000000..49125f5
--- /dev/null
+++ b/docs/u8c_seterr.3
@@ -0,0 +1,19 @@
+.TH "u8c_seterr" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_seterr - Set error - Set error and call error handler.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <u8c/errtyp.h>
+# include <uchar.h>
+extern bool u8c_seterr(char32_t const * const msg,enum u8c_errtyp _typ);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 10
diff --git a/docs/u8c_setfmt.3 b/docs/u8c_setfmt.3
new file mode 100644
index 0000000..105019e
--- /dev/null
+++ b/docs/u8c_setfmt.3
@@ -0,0 +1,18 @@
+.TH "u8c_setfmt" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_setfmt - Set format - Set format to be used by \f[B]u8c_fmt\f[R] and company.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdint.h>
+extern bool u8c_setfmt(uint_least8_t const base,uint_least8_t const endian);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_thrdsafe.3 b/docs/u8c_thrdsafe.3
new file mode 100644
index 0000000..b229734
--- /dev/null
+++ b/docs/u8c_thrdsafe.3
@@ -0,0 +1,22 @@
+.TH "u8c_thrdsafe" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_thrdsafe - Thread-safe - Whether or not u8c is thread-safe.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+extern bool const u8c_thrdsafe;
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The constant \f[B]u8c_thrdsafe\f[R] evaluates to \f[B]true\f[R] if u8c is thread-safe, that is, the following functions (that othwerise wouldn't be thread-safe) may be called from multiple threads: \f[B]u8c_geterr\f[R], \f[B]u8c_regerrhandl\f[R], \f[B]u8c_seterr\f[R], and \f[B]u8c_setfmt\f[R].
+.PP
+If it evaluates to \f[B]false\f[R], the functions listed may only be called from one thread.
+.PP
+The functions \f[B]u8c_end\f[R] and \f[B]u8c_init\f[R] may never be called from more than one thread.
+.SH VERSION
+.PP
+u8c 0
diff --git a/docs/u8c_u32alloc.3 b/docs/u8c_u32alloc.3
new file mode 100644
index 0000000..8288f55
--- /dev/null
+++ b/docs/u8c_u32alloc.3
@@ -0,0 +1,19 @@
+.TH "u8c_u32alloc" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32alloc - UTF-32 allocate - Allocate UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u32alloc(char32_t * * const u32,size_t const sz);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_u32cat.3 b/docs/u8c_u32cat.3
new file mode 100644
index 0000000..b600f9f
--- /dev/null
+++ b/docs/u8c_u32cat.3
@@ -0,0 +1,19 @@
+.TH "u8c_u32cat" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32cat - UTF-32 concatenate - Concatenate two UTF-32 strings.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u32cat(size_t * const sz,char32_t const * * const out,char32_t const * const lstr,char32_t const * const rstr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_u32cmp.3 b/docs/u8c_u32cmp.3
new file mode 100644
index 0000000..c4d41bd
--- /dev/null
+++ b/docs/u8c_u32cmp.3
@@ -0,0 +1,19 @@
+.TH "u8c_u32cmp" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32cmp - UTF-32 compare - Compare two UTF-32 strings.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stdint.h>
+# include <uchar.h>
+extern bool u8c_u32cmp(uint_least8_t * const res,char32_t const * const lstr,char32_t const * const rstr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 9
diff --git a/docs/u8c_u32cp.3 b/docs/u8c_u32cp.3
new file mode 100644
index 0000000..ad28884
--- /dev/null
+++ b/docs/u8c_u32cp.3
@@ -0,0 +1,19 @@
+.TH "u8c_u32cp" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32cp - UTF-32 copy - Copy an UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u32cp(size_t * const sz,char32_t const * * const out,char32_t const * const in);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 2
diff --git a/docs/u8c_u32fndchr.3 b/docs/u8c_u32fndchr.3
new file mode 100644
index 0000000..a7f688e
--- /dev/null
+++ b/docs/u8c_u32fndchr.3
@@ -0,0 +1,19 @@
+.TH "u8c_u32fndchr" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32fndchr - UTF-32 find character - Find the first occurence of an UTF-32 character in an UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u32fndchr(size_t * const pos,char32_t const * const in,char32_t const chr);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_u32fndpat.3 b/docs/u8c_u32fndpat.3
new file mode 100644
index 0000000..1caf194
--- /dev/null
+++ b/docs/u8c_u32fndpat.3
@@ -0,0 +1,19 @@
+.TH "u8c_u32fndpat" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32fndpat - UTF-32 find pattern - Find the first occurence of an UTF-32 pattern (string) in an UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u32fndpat(size_t * const pos,char32_t const * const in,char32_t const * const pat);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_u32free.3 b/docs/u8c_u32free.3
new file mode 100644
index 0000000..da74052
--- /dev/null
+++ b/docs/u8c_u32free.3
@@ -0,0 +1,18 @@
+.TH "u8c_u32free" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32free - UTF-32 free - Free UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <uchar.h>
+extern bool u8c_u32free(char32_t const * * const u32);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 14
diff --git a/docs/u8c_u32ins.3 b/docs/u8c_u32ins.3
new file mode 100644
index 0000000..ea62cae
--- /dev/null
+++ b/docs/u8c_u32ins.3
@@ -0,0 +1,19 @@
+.TH "u8c_u32ins" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32ins - UTF-32 insert - Insert an UTF-32 string into another UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u32ins(size_t * const sz,char32_t const * * const out,size_t const pos,char32_t const * const str0,char32_t const * const str1);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 19
diff --git a/docs/u8c_u32substr.3 b/docs/u8c_u32substr.3
new file mode 100644
index 0000000..b35bebe
--- /dev/null
+++ b/docs/u8c_u32substr.3
@@ -0,0 +1,19 @@
+.TH "u8c_u32substr" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32substr - UTF-32 sub-string - Get sub-string of an UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u32substr(char32_t const * * const out,size_t const start,size_t const len,char32_t const * const in);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_u32sz.3 b/docs/u8c_u32sz.3
new file mode 100644
index 0000000..0a7fab9
--- /dev/null
+++ b/docs/u8c_u32sz.3
@@ -0,0 +1,19 @@
+.TH "u8c_u32sz" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u32sz - UTF-32 size - Get the size of an UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u32sz(size_t * sz,char32_t const * in);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 2
diff --git a/docs/u8c_u8alloc.3 b/docs/u8c_u8alloc.3
new file mode 100644
index 0000000..8fbda08
--- /dev/null
+++ b/docs/u8c_u8alloc.3
@@ -0,0 +1,18 @@
+.TH "u8c_u8alloc" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u8alloc - UTF-8 allocate - Allocate UTF-8 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+extern bool u8c_u8alloc(unsigned char * * const u32,size_t const sz);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_u8dec.3 b/docs/u8c_u8dec.3
new file mode 100644
index 0000000..2afe4dd
--- /dev/null
+++ b/docs/u8c_u8dec.3
@@ -0,0 +1,27 @@
+.\" Automatically generated by Pandoc 2.14.0.2
+.\"
+.TH "" "" "" "" ""
+.hy
+.SH NAME
+.PP
+u8c_u8dec - UTF-8 decode - Convert an UTF-8 string to UTF-32.
+.SH DECLARATION
+.IP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u8dec(size_t * const sz,char32_t const * * const out,unsigned char const * const in);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The function \f[C]u8c_u8dec\f[R] converts the given UTF-8 string
+(\f[I]in\f[R]) to UTF-32 (\f[I]out\f[R]).
+.PP
+The size of the output string (excluding the null-terminator) is placed
+into \f[I]sz\f[R], if [\f[I]sz\f[R]] is not equal to \f[I]NULL\f[R].
+.SH VERSION
+.PP
+u8c 0
diff --git a/docs/u8c_u8enc.3 b/docs/u8c_u8enc.3
new file mode 100644
index 0000000..64feaf1
--- /dev/null
+++ b/docs/u8c_u8enc.3
@@ -0,0 +1,27 @@
+.\" Automatically generated by Pandoc 2.14.0.2
+.\"
+.TH "" "" "" "" ""
+.hy
+.SH NAME
+.PP
+u8c_u8enc - UTF-8 encode - Convert an UTF-32 string to UTF-8.
+.SH DECLARATION
+.IP
+.nf
+\f[C]
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u8enc(size_t * const sz,unsigned char const * * const out,char32_t const * const in);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+The function \f[C]u8c_u8enc\f[R] converts the given UTF-32 string
+(\f[B]in\f[R]) to UTF-8 (\f[B]out\f[R]).
+.PP
+The size of the output string (excluding the null-terminator) is placed
+into \f[B]sz\f[R], if [\f[B]sz\f[R]] is not equal to \f[I]NULL\f[R].
+.SH VERSION
+.PP
+u8c 0
diff --git a/docs/u8c_u8free.3 b/docs/u8c_u8free.3
new file mode 100644
index 0000000..8c2c0ba
--- /dev/null
+++ b/docs/u8c_u8free.3
@@ -0,0 +1,17 @@
+.TH "u8c_u8free" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_u8free - UTF-8 free - Free UTF-8 string and set it to \f[B]NULL\f[R].
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdbool.h>
+extern bool u8c_u8free(unsigned char const * * const u8);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_unimax.3 b/docs/u8c_unimax.3
new file mode 100644
index 0000000..7b35dc9
--- /dev/null
+++ b/docs/u8c_unimax.3
@@ -0,0 +1,18 @@
+.TH "u8c_unimax" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_unimax - Unicode maximum - Maximum valid Unicode codepoint.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdint.h>
+# include <uchar.h>
+# define u8c_unimax ((char32_t)UINT32_C(0x10FFFF))
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 16
diff --git a/docs/u8c_ver.3 b/docs/u8c_ver.3
new file mode 100644
index 0000000..7c2ea39
--- /dev/null
+++ b/docs/u8c_ver.3
@@ -0,0 +1,17 @@
+.TH "u8c_ver" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_ver - Version - Version of the u8c API.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdint.h>
+# define u8c_ver (UINT64_C(/* version */))
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 0
diff --git a/docs/u8c_vfmt.3 b/docs/u8c_vfmt.3
new file mode 100644
index 0000000..9b2f626
--- /dev/null
+++ b/docs/u8c_vfmt.3
@@ -0,0 +1,20 @@
+.TH "u8c_vfmt" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_vfmt - Variadic format - Format UTF-32 string.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdarg.h>
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_vfmt(size_t * const sz,char32_t const * * const out,char32_t const * const in,va_list args);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 2
diff --git a/docs/u8c_vprint.3 b/docs/u8c_vprint.3
new file mode 100644
index 0000000..5db1cee
--- /dev/null
+++ b/docs/u8c_vprint.3
@@ -0,0 +1,20 @@
+.TH "u8c_vprint" "3" "" "u8c" "u8c API Manual"
+.SH NAME
+.PP
+u8c_vprint - Variadic print - Format UTF-32 and print it to file.
+.SH DECLARATION
+.PP
+.nf
+\f[C]
+# include <stdarg.h>
+# include <stdbool.h>
+# include <stdio.h>
+# include <uchar.h>
+extern bool u8c_vprint(FILE * fp,char32_t const * const msg,va_list args);
+\f[R]
+.fi
+.SH DESCRIPTION
+.PP
+.SH VERSION
+.PP
+u8c 2
diff --git a/include/u8c/end.h b/include/u8c/end.h
index 01c8c24..5cc7922 100644
--- a/include/u8c/end.h
+++ b/include/u8c/end.h
@@ -13,7 +13,6 @@
If not, see <https://www.gnu.org/licenses/>.
*/
-/* End */
# if !defined(u8c_sym_end)
# define u8c_sym_end
# include <stdbool.h>
diff --git a/include/u8c/errhandltyp.h b/include/u8c/errhandltyp.h
new file mode 100644
index 0000000..310f6a6
--- /dev/null
+++ b/include/u8c/errhandltyp.h
@@ -0,0 +1,20 @@
+/*
+ Copyright 2021 Gabriel Jensen
+
+ This file is part of u8c.
+
+ u8c is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+ u8c is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with u8c.
+
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+# if !defined(u8c_sym_errhandltyp)
+# define u8c_sym_errhandltyp
+# include <u8c/errtyp.h>
+typedef void (* u8c_errhandltyp)(enum u8c_errtyp);
+# endif
diff --git a/include/u8c/errtyp.h b/include/u8c/errtyp.h
new file mode 100644
index 0000000..00a6ef8
--- /dev/null
+++ b/include/u8c/errtyp.h
@@ -0,0 +1,29 @@
+/*
+ Copyright 2021 Gabriel Jensen
+
+ This file is part of u8c.
+
+ u8c is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+ u8c is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with u8c.
+
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+/* Error type */
+# if !defined(u8c_sym_errtyp)
+# define u8c_sym_errtyp
+enum u8c_errtyp {
+ u8c_errtyp_badalloc, /* Bad allocation */
+ u8c_errtyp_badio, /* Bad input or output */
+ u8c_errtyp_u32oor, /* UTF-32 out of range */
+ u8c_errtyp_u8oor, /* UTF-8 out of range */
+ u8c_errtyp_deferr, /* Default error */
+ u8c_errtyp_untermin, /* Unterminated input */
+ u8c_errtyp_maxerrtyp, /* Maximum error type */
+ u8c_errtyp_all, /* All */
+};
+# endif
diff --git a/include/u8c/init.h b/include/u8c/init.h
index 1aa4804..e19cb5b 100644
--- a/include/u8c/init.h
+++ b/include/u8c/init.h
@@ -17,5 +17,6 @@
# if !defined(u8c_sym_init)
# define u8c_sym_init
# include <stdbool.h>
+# include <u8c/errtyp.h>
extern bool u8c_init(void);
# endif
diff --git a/include/u8c/regerrhandl.h b/include/u8c/regerrhandl.h
new file mode 100644
index 0000000..d94869a
--- /dev/null
+++ b/include/u8c/regerrhandl.h
@@ -0,0 +1,23 @@
+/*
+ Copyright 2021 Gabriel Jensen
+
+ This file is part of u8c.
+
+ u8c is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+ u8c is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with u8c.
+
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+/* Register error handler */
+# if !defined(u8c_sym_regerrhandl)
+# define u8c_sym_regerrhandl
+# include <stdbool.h>
+# include <u8c/errhandltyp.h>
+# include <u8c/errtyp.h>
+extern bool u8c_regerrhandl(enum u8c_errtyp typ,u8c_errhandltyp errhandl);
+# endif
diff --git a/include/u8c/seterr.h b/include/u8c/seterr.h
index 3f3e793..b143f5d 100644
--- a/include/u8c/seterr.h
+++ b/include/u8c/seterr.h
@@ -17,6 +17,7 @@
# if !defined(u8c_sym_seterr)
# define u8c_sym_seterr
# include <stdbool.h>
+# include <u8c/errtyp.h>
# include <uchar.h>
-extern bool u8c_seterr(char32_t const * const msg);
+extern bool u8c_seterr(char32_t const * const msg,enum u8c_errtyp _typ);
# endif
diff --git a/include/u8c/u32cmp.h b/include/u8c/u32cmp.h
index ffc2729..d638255 100644
--- a/include/u8c/u32cmp.h
+++ b/include/u8c/u32cmp.h
@@ -13,7 +13,6 @@
If not, see <https://www.gnu.org/licenses/>.
*/
-/* UTF-32 compare */
# if !defined(luma_sym_u32cmp)
# define luma_sym_u32cmp
# include <stdbool.h>
diff --git a/include/u8c/u32cp.h b/include/u8c/u32cp.h
index 01e2ae1..a79d087 100644
--- a/include/u8c/u32cp.h
+++ b/include/u8c/u32cp.h
@@ -13,7 +13,6 @@
If not, see <https://www.gnu.org/licenses/>.
*/
-/* UTF-32 copy */
# if !defined(luma_sym_u32cp)
# define luma_sym_u32cp
# include <stdbool.h>
diff --git a/include/u8c/u32fndchr.h b/include/u8c/u32fndchr.h
index d52682d..2ba83a1 100644
--- a/include/u8c/u32fndchr.h
+++ b/include/u8c/u32fndchr.h
@@ -13,7 +13,6 @@
If not, see <https://www.gnu.org/licenses/>.
*/
-/* UTF-32 find character */
# if !defined(luma_sym_u32fndchr)
# define luma_sym_u32fndchr
# include <stdbool.h>
diff --git a/include/u8c/u32ins.h b/include/u8c/u32ins.h
new file mode 100644
index 0000000..70a2440
--- /dev/null
+++ b/include/u8c/u32ins.h
@@ -0,0 +1,23 @@
+/*
+ Copyright 2021 Gabriel Jensen
+
+ This file is part of u8c.
+
+ u8c is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+ u8c is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with u8c.
+
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+/* UTF-32 insert */
+# if !defined(luma_sym_u32ins)
+# define luma_sym_u32ins
+# include <stdbool.h>
+# include <stddef.h>
+# include <uchar.h>
+extern bool u8c_u32ins(size_t * const sz,char32_t const * * const out,size_t const pos,char32_t const * const str0,char32_t const * const str1);
+# endif
diff --git a/include/u8c/ver.h b/include/u8c/ver.h
index 4fa1b51..3f59f1a 100644
--- a/include/u8c/ver.h
+++ b/include/u8c/ver.h
@@ -17,5 +17,5 @@
# if !defined(u8c_sym_ver)
# define u8c_sym_ver
# include <stdint.h>
-# define u8c_ver (UINT64_C(0x14))
+# define u8c_ver (UINT64_C(0x15))
# endif
diff --git a/src/u8c/dat.c b/src/u8c/dat.c
index 0fcf492..26d17ef 100644
--- a/src/u8c/dat.c
+++ b/src/u8c/dat.c
@@ -19,7 +19,7 @@
# include <stddef.h>
# include <stdint.h>
# include <u8c/SIZE_C.h>
-struct u8c_dattyp u8c_dat = (struct u8c_dattyp){
+struct u8c_dattyp u8c_dat = {
.err = NULL,
.fmtendian = false,
.stat = UINT8_C(0x0),
diff --git a/src/u8c/dattyp.h b/src/u8c/dattyp.h
index d094151..1a1e830 100644
--- a/src/u8c/dattyp.h
+++ b/src/u8c/dattyp.h
@@ -17,6 +17,8 @@
# define u8c_sym_dattyp
# include <stdbool.h>
# include <stdint.h>
+# include <u8c/errhandltyp.h>
+# include <u8c/errtyp.h>
# include <u8c/SIZE_C.h>
# include <uchar.h>
# if defined(u8c_bethrdsafe)
@@ -24,13 +26,16 @@
# endif
struct u8c_dattyp {
bool fmtendian;
+ unsigned char pad0[sizeof(void(*)(void)) - SIZE_C(0x1)]; /* Padding. */
char32_t const * err;
- unsigned char pad0[sizeof(void(*)(void)) - SIZE_C(0x1)];
+ u8c_errhandltyp errhandls[u8c_errtyp_maxerrtyp];
uint_least8_t fmtbase;
uint_least8_t stat;
# if defined(u8c_bethrdsafe)
- mtx_t errlock;
- mtx_t fmtlock;
+ unsigned char pad1[sizeof(void(*)(void)) - SIZE_C(0x2)]; /* Padding. */
+ mtx_t errlock;
+ mtx_t errhandlslock;
+ mtx_t fmtlock;
# endif
};
# endif
diff --git a/src/u8c/geterr.c b/src/u8c/geterr.c
index a63ae20..65b8eba 100644
--- a/src/u8c/geterr.c
+++ b/src/u8c/geterr.c
@@ -27,9 +27,9 @@ bool u8c_geterr(size_t * const _sz,char32_t const * * const _out) {
# endif
u8c_u32cp(_sz,_out,u8c_dat.err);
u8c_u32free(&u8c_dat.err);
+ u8c_u32cp(_sz,&u8c_dat.err,U"");
# if defined(u8c_bethrdsafe)
mtx_unlock(&u8c_dat.errlock);
# endif
- u8c_seterr((uint_least32_t[]){UINT32_C(0x0),});
return false;
}
diff --git a/src/u8c/init.c b/src/u8c/init.c
index f625bce..f2e4948 100644
--- a/src/u8c/init.c
+++ b/src/u8c/init.c
@@ -14,16 +14,18 @@
If not, see <https://www.gnu.org/licenses/>.
*/
# include "dat.h"
+# include <setjmp.h>
# include <stdbool.h>
# include <stddef.h>
# include <stdint.h>
+# include <u8c/errtyp.h>
# include <u8c/init.h>
# include <u8c/seterr.h>
# include <u8c/u32cp.h>
# if defined(u8c_bethrdsafe)
# include <threads.h>
# endif
-bool u8c_init(void) {
+bool u8c_init() {
/* Initialise mutexes: */
# if defined(u8c_bethrdsafe)
if(mtx_init(&u8c_dat.errlock,mtx_plain) == thrd_error) {
@@ -35,7 +37,7 @@ bool u8c_init(void) {
# endif
/* Set default error message: */
u8c_dat.err = NULL;
- u8c_seterr((uint_least32_t[]){UINT32_C(0x0),});
+ u8c_seterr(U"",u8c_errtyp_deferr);
/* Set status: */
u8c_dat.stat = UINT8_C(0x1);
return false;
diff --git a/src/u8c/println.c b/src/u8c/println.c
index fbfd046..76b0f72 100644
--- a/src/u8c/println.c
+++ b/src/u8c/println.c
@@ -18,6 +18,7 @@
# include <stdbool.h>
# include <stdint.h>
# include <stdio.h>
+# include <u8c/errtyp.h>
# include <u8c/println.h>
# include <u8c/seterr.h>
# include <u8c/vprint.h>
@@ -29,7 +30,7 @@ bool u8c_println(FILE * _fp,char32_t const * const _msg,...) {
return true;
}
if(fputc(0xA,stdout) == EOF) {
- u8c_seterr((uint_least32_t[]){UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x63),UINT32_C(0x5F),UINT32_C(0x70),UINT32_C(0x72),UINT32_C(0x69),UINT32_C(0x6E),UINT32_C(0x74),UINT32_C(0x6C),UINT32_C(0x6E),UINT32_C(0x3A),UINT32_C(0x20),UINT32_C(0x66),UINT32_C(0x70),UINT32_C(0x75),UINT32_C(0x74),UINT32_C(0x63),UINT32_C(0x3A),UINT32_C(0x20),UINT32_C(0x55),UINT32_C(0x6E),UINT32_C(0x61),UINT32_C(0x62),UINT32_C(0x6C),UINT32_C(0x65),UINT32_C(0x20),UINT32_C(0x74),UINT32_C(0x6F),UINT32_C(0x20),UINT32_C(0x77),UINT32_C(0x72),UINT32_C(0x69),UINT32_C(0x74),UINT32_C(0x65),UINT32_C(0x20),UINT32_C(0x74),UINT32_C(0x6F),UINT32_C(0x20),UINT32_C(0x73),UINT32_C(0x74),UINT32_C(0x64),UINT32_C(0x6F),UINT32_C(0x75),UINT32_C(0x74),UINT32_C(0x2E),UINT32_C(0x0),}); /* u8c_println: fputc: Unable to write to stdout. */
+ u8c_seterr(U"u8c_println: Unable to write to stdout (end of file).",u8c_errtyp_badio);
return false;
}
va_end(args);
diff --git a/src/u8c/regerrhandl.c b/src/u8c/regerrhandl.c
new file mode 100644
index 0000000..6a0d82f
--- /dev/null
+++ b/src/u8c/regerrhandl.c
@@ -0,0 +1,41 @@
+/*
+ Copyright 2021 Gabriel Jensen
+
+ This file is part of u8c.
+
+ u8c is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+ u8c is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with u8c.
+
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+# include "dat.h"
+# include <stdbool.h>
+# include <stddef.h>
+# include <u8c/errhandltyp.h>
+# include <u8c/errtyp.h>
+# include <u8c/regerrhandl.h>
+static void u8c_regerrhandl_seterrhandl(enum u8c_errtyp _typ,u8c_errhandltyp _errhandl) {
+ u8c_dat.errhandls[(size_t)_typ] = _errhandl;
+}
+bool u8c_regerrhandl(enum u8c_errtyp _typ,u8c_errhandltyp _errhandl) {
+# if defined(u8c_bethrdsafe)
+ mtx_lock(&u8c_dat.errhandlslock);
+# endif
+ if(_typ == u8c_errtyp_all) {
+ for(register int n = 0x0;n < (int)u8c_errtyp_maxerrtyp;n += 0x1) {
+ u8c_regerrhandl_seterrhandl((enum u8c_errtyp)n,_errhandl);
+ }
+ }
+ else {
+ u8c_regerrhandl_seterrhandl(_typ,_errhandl);
+ }
+# if defined(u8c_bethrdsafe)
+ mtx_unlock(&u8c_dat.errhandlslock);
+# endif
+ return false;
+}
diff --git a/src/u8c/seterr.c b/src/u8c/seterr.c
index 7c7fb12..adde683 100644
--- a/src/u8c/seterr.c
+++ b/src/u8c/seterr.c
@@ -16,16 +16,17 @@
# include "dat.h"
# include <assert.h>
# include <stdbool.h>
+# include <stddef.h>
# include <stdint.h>
-# include <stdlib.h>
# include <u8c/dbgprint.h>
+# include <u8c/errtyp.h>
# include <u8c/seterr.h>
# include <u8c/u32cp.h>
# include <u8c/u32free.h>
# if defined(u8c_bethrdsafe)
# include <threads.h>
# endif
-bool u8c_seterr(char32_t const * const _msg) {
+bool u8c_seterr(char32_t const * const _msg,enum u8c_errtyp _typ) {
assert(_msg != NULL);
//u8c_dbgprint(_msg);
# if defined(u8c_bethrdsafe)
@@ -36,5 +37,14 @@ bool u8c_seterr(char32_t const * const _msg) {
# if defined(u8c_bethrdsafe)
mtx_unlock(&u8c_dat.errlock);
# endif
+# if defined(u8c_bethrdsafe)
+ mtx_lock(&u8c_dat.errhandlslock);
+# endif
+ if(u8c_dat.errhandls[(size_t)_typ] != NULL) {
+ u8c_dat.errhandls[(size_t)_typ](_typ);
+ }
+# if defined(u8c_bethrdsafe)
+ mtx_unlock(&u8c_dat.errhandlslock);
+# endif
return false;
}
diff --git a/src/u8c/u32alloc.c b/src/u8c/u32alloc.c
index 804d564..ddd5493 100644
--- a/src/u8c/u32alloc.c
+++ b/src/u8c/u32alloc.c
@@ -13,16 +13,19 @@
If not, see <https://www.gnu.org/licenses/>.
*/
+# include "dat.h"
+# include <setjmp.h>
# include <stdbool.h>
# include <stdlib.h>
+# include <u8c/errtyp.h>
# include <u8c/seterr.h>
# include <u8c/u32alloc.h>
# include <uchar.h>
bool u8c_u32alloc(char32_t * * const _u32,size_t const _sz) {
char32_t * arr = NULL;
if((arr = calloc(sizeof *arr,_sz)) == NULL) {
- u8c_seterr(U"u8c_u32alloc: Unable to allocate resources (not enough memory?).");
- return true;
+ u8c_seterr(U"u8c_u32alloc: Unable to allocate resources (not enough memory?).",u8c_errtyp_badalloc);
+ return false;
}
*_u32 = arr;
return false;
diff --git a/src/u8c/u32cat.c b/src/u8c/u32cat.c
index 409030e..b2b6773 100644
--- a/src/u8c/u32cat.c
+++ b/src/u8c/u32cat.c
@@ -33,19 +33,19 @@ bool u8c_u32cat(size_t * const _sz,char32_t const * * const _out,char32_t const
size_t rsz = SIZE_C(0x0);
u8c_u32sz(&lsz,_lstr);
u8c_u32sz(&rsz,_rstr);
- sz = lsz + rsz - SIZE_C(0x1);
+ sz = lsz + rsz;
if(_sz != NULL) {
*_sz = sz;
}
char32_t * out = NULL;
if(u8c_u32alloc(&out,sz + SIZE_C(0x1))) {
- return false;
+ return true;
}
- for(register size_t n = SIZE_C(0x0);n < lsz - SIZE_C(0x1);n += SIZE_C(0x1)) {
+ for(register size_t n = SIZE_C(0x0);n < lsz;n += SIZE_C(0x1)) {
out[n] = _lstr[n];
}
for(register size_t n = SIZE_C(0x0);n < rsz;n += SIZE_C(0x1)) {
- out[n + lsz - SIZE_C(0x1)] = _rstr[n];
+ out[n + lsz] = _rstr[n];
}
u8c_u32free(_out);
*_out = out;
diff --git a/src/u8c/u32cmp.c b/src/u8c/u32cmp.c
index 1dabfef..5c06e30 100644
--- a/src/u8c/u32cmp.c
+++ b/src/u8c/u32cmp.c
@@ -17,6 +17,7 @@
# include <stdbool.h>
# include <stddef.h>
# include <stdint.h>
+# include <u8c/errtyp.h>
# include <u8c/seterr.h>
# include <u8c/SIZE_C.h>
# include <u8c/u32cmp.h>
@@ -40,6 +41,6 @@ bool u8c_u32cmp(uint_least8_t * const _res,char32_t const * const _lstr,char32_t
return false;
}
}
- u8c_seterr((uint_least32_t[]){UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x63),UINT32_C(0x5F),UINT32_C(0x75),UINT32_C(0x33),UINT32_C(0x32),UINT32_C(0x63),UINT32_C(0x6D),UINT32_C(0x70),UINT32_C(0x3A),UINT32_C(0x20),UINT32_C(0x55),UINT32_C(0x6E),UINT32_C(0x74),UINT32_C(0x65),UINT32_C(0x72),UINT32_C(0x6D),UINT32_C(0x69),UINT32_C(0x6E),UINT32_C(0x61),UINT32_C(0x74),UINT32_C(0x65),UINT32_C(0x64),UINT32_C(0x20),UINT32_C(0x69),UINT32_C(0x6E),UINT32_C(0x70),UINT32_C(0x75),UINT32_C(0x74),UINT32_C(0x2E),UINT32_C(0x0),}); /* u8c_u32cmp: Unterminated input. */
+ u8c_seterr(U"u8c_u32cmp: Unterminated input.",u8c_errtyp_untermin);
return true;
}
diff --git a/src/u8c/u32fndchr.c b/src/u8c/u32fndchr.c
index ca83998..ab4b5e1 100644
--- a/src/u8c/u32fndchr.c
+++ b/src/u8c/u32fndchr.c
@@ -18,6 +18,7 @@
# include <stddef.h>
# include <stdint.h>
# include <u8c/SIZE_C.h>
+# include <u8c/errtyp.h>
# include <u8c/seterr.h>
# include <u8c/u32fndchr.h>
# include <u8c/u32sz.h>
@@ -25,16 +26,21 @@ bool u8c_u32fndchr(size_t * const _pos,char32_t const * const _in,char32_t const
assert(_pos != NULL);
assert(_in != NULL);
for(register size_t n = SIZE_C(0x0);n <= SIZE_MAX;n += SIZE_C(0x1)) {
- if(_in[n] == UINT32_C(0x0) && _chr != UINT32_C(0x0)) {
+ register uint_least32_t const tmp = _in[n];
+ if(tmp == UINT32_C(0x0)) {
+ if(_chr == UINT32_C(0x0)) {
+ *_pos = n;
+ return false;
+ }
*_pos = SIZE_C(-0x1);
return true;
}
- if(_in[n] == _chr) {
+ if(tmp == _chr) {
*_pos = n;
return false;
}
}
- u8c_seterr(U"u8c_u32fndchr: Unterminated input.");
+ u8c_seterr(U"u8c_u32fndchr: Unterminated input.",u8c_errtyp_badio);
*_pos = SIZE_C(-0x1);
return true;
}
diff --git a/src/u8c/u32free.c b/src/u8c/u32free.c
index 62b43ef..b57e392 100644
--- a/src/u8c/u32free.c
+++ b/src/u8c/u32free.c
@@ -18,7 +18,7 @@
# include <stdlib.h>
# include <u8c/u32free.h>
bool u8c_u32free(char32_t const * * const _u32) {
- free((char32_t *)*_u32);
+ free((char32_t *)*_u32); /* This cast does indeed discard a const-qualifier, but it is not undefined behaviour, as the array must have been allocated by calloc or malloc, meaning it's original type is not const-qualified. */
*_u32 = NULL;
return false;
}
diff --git a/src/u8c/u32ins.c b/src/u8c/u32ins.c
new file mode 100644
index 0000000..f5d9d4e
--- /dev/null
+++ b/src/u8c/u32ins.c
@@ -0,0 +1,49 @@
+/*
+ Copyright 2021 Gabriel Jensen
+
+ This file is part of u8c.
+
+ u8c is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+ u8c is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with u8c.
+
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+# include <assert.h>
+# include <stdbool.h>
+# include <stddef.h>
+# include <u8c/SIZE_C.h>
+# include <u8c/u32alloc.h>
+# include <u8c/u32cat.h>
+# include <u8c/u32free.h>
+# include <u8c/u32ins.h>
+# include <u8c/u32substr.h>
+# include <uchar.h>
+bool u8c_u32ins(size_t * const _sz,char32_t const * * const _out,size_t const _pos,char32_t const * const _str0,char32_t const * const _str1) {
+ assert(_out != NULL);
+ assert(_str0 != NULL);
+ assert(_str1 != NULL);
+ char32_t const * lstr = NULL;
+ char32_t const * rstr = NULL;
+ u8c_u32substr(&lstr,SIZE_C(0x0),_pos - SIZE_C(0x1),_str0);
+ u8c_u32substr(&rstr,_pos,SIZE_C(0x0),_str0);
+ size_t sz = SIZE_C(0x0);
+ char32_t const * out = NULL;
+ {
+ char32_t const * tmp = NULL;
+ u8c_u32cat(NULL,&tmp,lstr,_str1);
+ u8c_u32free(&lstr);
+ u8c_u32cat(NULL,&out,tmp,rstr);
+ u8c_u32free(&rstr);
+ u8c_u32free(&tmp);
+ }
+ if(_sz != NULL) {
+ *_sz = sz;
+ }
+ *_out = out;
+ return false;
+}
diff --git a/src/u8c/u32substr.c b/src/u8c/u32substr.c
index 2a30b3b..f23cffa 100644
--- a/src/u8c/u32substr.c
+++ b/src/u8c/u32substr.c
@@ -33,12 +33,12 @@ bool u8c_u32substr(char32_t const * * const _out,size_t const _start,size_t cons
len = insz - _start;
}
if(insz < _start + len) {
- return false;
+ return true;
}
size_t const outsz = len + SIZE_C(0x2);
char32_t * out = NULL;
if(u8c_u32alloc(&out,outsz)) {
- return false;
+ return true;
}
for(register size_t n = SIZE_C(0x0);n <= len;n += SIZE_C(0x1)) {
out[n] = _in[n + _start];
diff --git a/src/u8c/u8alloc.c b/src/u8c/u8alloc.c
index a364acf..4e7bc3d 100644
--- a/src/u8c/u8alloc.c
+++ b/src/u8c/u8alloc.c
@@ -13,15 +13,18 @@
If not, see <https://www.gnu.org/licenses/>.
*/
+# include "dat.h"
+# include <setjmp.h>
# include <stdbool.h>
# include <stdlib.h>
+# include <u8c/errtyp.h>
# include <u8c/seterr.h>
# include <u8c/u8alloc.h>
bool u8c_u8alloc(unsigned char * * const _u8,size_t const _sz) {
unsigned char * arr = NULL;
if((arr = calloc(sizeof *arr,_sz)) == NULL) {
- u8c_seterr(U"u8c_u8alloc: Unable to allocate resources (not enough memory?).");
- return true;
+ u8c_seterr(U"u8c_u8alloc: Unable to allocate resources (not enough memory?).",u8c_errtyp_badalloc);
+ return false;
}
*_u8 = arr;
return false;
diff --git a/src/u8c/u8dec.c b/src/u8c/u8dec.c
index bbc6e94..8e9c2f2 100644
--- a/src/u8c/u8dec.c
+++ b/src/u8c/u8dec.c
@@ -18,6 +18,7 @@
# include <stddef.h>
# include <stdint.h>
# include <u8c/SIZE_C.h>
+# include <u8c/errtyp.h>
# include <u8c/seterr.h>
# include <u8c/u32alloc.h>
# include <u8c/u32free.h>
@@ -35,7 +36,7 @@ bool u8c_u8dec(size_t * const _sz,char32_t const * * const _out,unsigned char co
goto nottoobig;
}
if(tmp >= UINT8_C(0xF8)) { /* Too big. */
- u8c_seterr(U"u8c_u8dec: Character out of range (too big).");
+ u8c_seterr(U"u8c_u8dec: Character out of range (too big).",u8c_errtyp_u8oor);
return true;
}
if(tmp >= UINT8_C(0xF0)) { /* Four byte. */
@@ -54,7 +55,7 @@ bool u8c_u8dec(size_t * const _sz,char32_t const * * const _out,unsigned char co
n += SIZE_C(0x1);
}
/* Input is not null-terminated. */
- u8c_seterr(U"u8c_u8dec: Unterminated input.");
+ u8c_seterr(U"u8c_u8dec: Unterminated input.",u8c_errtyp_untermin);
return true;
nottoobig:;
if(_sz != NULL) {
diff --git a/src/u8c/u8enc.c b/src/u8c/u8enc.c
index 60bc724..541dd8d 100644
--- a/src/u8c/u8enc.c
+++ b/src/u8c/u8enc.c
@@ -18,6 +18,7 @@
# include <stddef.h>
# include <stdint.h>
# include <u8c/SIZE_C.h>
+# include <u8c/errtyp.h>
# include <u8c/seterr.h>
# include <u8c/u8alloc.h>
# include <u8c/u8enc.h>
@@ -32,7 +33,7 @@ bool u8c_u8enc(size_t * const _sz,unsigned char const * * const _out,char32_t co
for(register size_t n = SIZE_C(0x0);n <= SIZE_MAX;n += SIZE_C(0x1)) { /* First pass: get size of input array, and determine size of output array. */
register char32_t const tmp = _in[n];
if(tmp > u8c_unimax) { /* Codepoint out of range. */
- u8c_seterr(U"u8c_u8enc: Codepoint out of range (too big).");
+ u8c_seterr(U"u8c_u8enc: Codepoint out of range (too big).",u8c_errtyp_u32oor);
return true;
}
if(tmp >= UINT32_C(0x10000)) { /* 4 bytes. */
@@ -54,7 +55,7 @@ bool u8c_u8enc(size_t * const _sz,unsigned char const * * const _out,char32_t co
goto nottoobig;
}
}
- u8c_seterr(U"u8c_u8enc: Unterminated input.");
+ u8c_seterr(U"u8c_u8enc: Unterminated input.",u8c_errtyp_untermin);
return true;
nottoobig:;
if(_sz != NULL) {
@@ -62,7 +63,6 @@ nottoobig:;
}
unsigned char * out = NULL;
if(u8c_u8alloc(&out,outsz + SIZE_C(0x1))) {
- u8c_seterr(U"u8c_u32enc: Unable to allocate resources (not enough memory?).");
return true;
}
for(register size_t n = SIZE_C(0x0), outn = SIZE_C(0x0);n < insz;n += SIZE_C(0x1),outn += SIZE_C(0x1)) { /* Second pass: encode each codepoint into UTF-8. */
diff --git a/src/u8c/vprint.c b/src/u8c/vprint.c
index 6dc30ae..a86afcf 100644
--- a/src/u8c/vprint.c
+++ b/src/u8c/vprint.c
@@ -20,6 +20,7 @@
# include <stdio.h>
# include <stdlib.h>
# include <u8c/SIZE_C.h>
+# include <u8c/errtyp.h>
# include <u8c/seterr.h>
# include <u8c/u32free.h>
# include <u8c/u8enc.h>
@@ -36,7 +37,7 @@ bool u8c_vprint(FILE * _fp,char32_t const * const _msg,va_list _args) {
u8c_u8enc(&str1sz,&str1,str0);
assert(str1sz > SIZE_C(0x0));
if(fwrite(str1,sizeof(uint_least8_t),str1sz - SIZE_C(0x1),_fp) < str1sz - SIZE_C(0x1)) {
- u8c_seterr(U"u8c_vprint: fwrite: Unable to write to stdout.");
+ u8c_seterr(U"u8c_vprint: fwrite: Unable to write to stdout.",u8c_errtyp_badio);
return true;
}
u8c_u32free(&str0);
diff --git a/test.c b/test.c
index 178f558..d3a596e 100644
--- a/test.c
+++ b/test.c
@@ -1,4 +1,5 @@
# include <inttypes.h>
+# include <setjmp.h>
# include <stdarg.h>
# include <stdint.h>
# include <stdio.h>
@@ -22,6 +23,7 @@
# include <u8c/isspace.h>
# include <u8c/print.h>
# include <u8c/println.h>
+# include <u8c/regerrhandl.h>
# include <u8c/seterr.h>
# include <u8c/setfmt.h>
# include <u8c/thrdsafe.h>
@@ -31,6 +33,7 @@
# include <u8c/u32fndchr.h>
# include <u8c/u32fndpat.h>
# include <u8c/u32free.h>
+# include <u8c/u32ins.h>
# include <u8c/u32substr.h>
# include <u8c/u32sz.h>
# include <u8c/u8dec.h>
@@ -42,20 +45,25 @@
static void testmsg(char const * fmt,...) {
va_list args;
va_start(args,fmt);
- printf("\n+->\n| \x1b[38:2::169:225:61mTesting\x1b[0m \"");
+ /* printf("\n+->\n| \x1b[38:2:169:225:61mTesting\x1b[0m \""); */ /* This command works in all of the terminals I tested, except Konsole (whic is funny, because it's xterm-based, and xterm supports it). */
+ printf("\n+->\n| \x1b[38;2;169;225;61mTesting\x1b[0m \"");
vprintf(fmt,args);
printf("\"...\n+->\n\n");
va_end(args);
}
static void testmsgdone() {
- printf("\n+->\n| \x1b[38:2::61:225:169mDone\x1b[0m!\n+->\n");
+ /* printf("\n+->\n| \x1b[38:2::61:225:169mDone\x1b[0m!\n+->\n"); */
+ printf("\n+->\n| \x1b[38;2;61;225;169mDone\x1b[0m!\n+->\n");
+}
+static void errhandl(enum u8c_errtyp errtyp) {
+ printf(":: Error handler called with type %d.\n",(int)errtyp);
}
int main(void) {
if(u8c_init()) {
printf("Unable to initialise u8c!\n");
exit(EXIT_FAILURE);
}
- atexit((void (*)(void))&u8c_end);
+ u8c_regerrhandl(u8c_errtyp_all,errhandl);
u8c_setfmt(UINT8_C(0xC),UINT8_C(0x1));
printf("u8c version: %" PRIXLEAST64 ".\n",u8c_ver);
printf("Debug build: %" PRIXLEAST8 ".\n",u8c_dbg);
@@ -66,9 +74,9 @@ int main(void) {
u8c_geterr(NULL,&err);
printf("default error message: ");
u8c_println(stdout,err);
- u8c_seterr(U"Gluchwein!");
+ u8c_seterr(U"Gluchwein!",u8c_errtyp_deferr);
u8c_geterr(NULL,&err);
- printf(" set error message: ");
+ printf("set error message: ");
u8c_println(stdout,err);
u8c_u32free(&err);
}
@@ -193,8 +201,8 @@ int main(void) {
testmsgdone();
testmsg("string concatenation");
{
- char32_t const * str0 = U"Free as in freedom!";
- char32_t const * str1 = U" GNU";
+ char32_t const * str0 = U"Free_as_in";
+ char32_t const * str1 = U"_freedom!";
char32_t const * str2 = NULL;
u8c_u32cat(NULL,&str2,str0,str1);
printf("string #0: ");
@@ -209,7 +217,7 @@ int main(void) {
testmsgdone();
testmsg("sub-strings");
{
- char32_t const * str0 = U"I wish to suck big duck.";
+ char32_t const * str0 = U"I_wish_to_suck_big_duck.";
char32_t const * str1 = NULL;
u8c_u32substr(&str1,SIZE_C(0x0),SIZE_C(0xE),str0);
char32_t const * str2 = NULL;
@@ -268,5 +276,21 @@ int main(void) {
printf("Position of \"forever\": %zu\n",pos1);
}
testmsgdone();
- u8c_abrt(__FILE__,(long long)__LINE__,__func__,"Testing u8c_abort");
+ testmsg("string insertion");
+ {
+ char32_t const * str0 = U"There_is_I_love.";
+ char32_t const * str1 = U"just_somebody_that_";
+ char32_t const * str2 = NULL;
+ u8c_u32ins(NULL,&str2,SIZE_C(0x9),str0,str1);
+ printf("String #0: ");
+ u8c_println(stdout,str0);
+ printf("String #1: ");
+ u8c_println(stdout,str1);
+ printf("String #2: ");
+ u8c_println(stdout,str2);
+ u8c_u32free(&str2);
+ }
+ testmsgdone();
+ u8c_end();
+ exit(EXIT_SUCCESS);
}