diff options
74 files changed, 1311 insertions, 131 deletions
@@ -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); @@ -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); } |