diff options
49 files changed, 1298 insertions, 276 deletions
@@ -1,2 +1,4 @@ *.o *.so +/test +/txttolit @@ -1,40 +1,83 @@ -CC = clang -CFLAGS = -std=c17 -Wall -Wextra -Wpedantic -fPIC -Iinclude -march=native -mtune=native -O3 -ifneq ($(debug),1) -CFLAGS += -DNDEBUG -else +CC = clang +CFLAGS = -std=c17 -Weverything -Wno-c99-compat -Wno-format-nonliteral -Wpedantic -Iinclude -march=native -mtune=native -O3 +CFLAGS0 = $(CFLAGS) -g -L. -lu8c -o $@ $^ +CFLAGS += -fPIC +ifneq ($(thrdsafe),0) +CFLAGS += -Du8c_bethrdsafe +endif +ifeq ($(debug),1) CFLAGS += -g +else +CFLAGS += -DNDEBUG endif -LDFLAGS = -shared +LDFLAGS = -shared -lpthread SRCS = \ - src/u8c/free.c \ + src/u8c/debug.c \ + src/u8c/end.c \ + src/u8c/err.c \ + src/u8c/errlock.c \ + src/u8c/fmt.c \ + src/u8c/geterr.c \ + src/u8c/init.c \ src/u8c/print.c \ + src/u8c/println.c \ + src/u8c/seterr.c \ + src/u8c/stat.c \ + src/u8c/thrdsafe.c \ + src/u8c/u32cp.c \ + src/u8c/u32sz.c \ src/u8c/u8dec.c \ - src/u8c/u8enc.c + src/u8c/u8enc.c \ + src/u8c/vfmt.c \ + src/u8c/vprint.c HDRS = \ + include/u8c.h \ + include/u8c/col.h \ + include/u8c/dbgprint.h \ + include/u8c/debug.h \ + include/u8c/end.h \ + include/u8c/fmt.h \ include/u8c/fmttyp.h \ - include/u8c/free.h \ + include/u8c/geterr.h \ + include/u8c/init.h \ include/u8c/print.h \ + include/u8c/println.h \ + include/u8c/SIZE_C.h \ + include/u8c/thrdsafe.h \ + include/u8c/u32cp.h \ + include/u8c/u32sz.h \ include/u8c/u8dec.h \ - include/u8c/u8enc.h + include/u8c/u8enc.h \ + include/u8c/ver.h \ + include/u8c/vfmt.h \ + include/u8c/vprint.h +HDRS_PRIV = \ + src/u8c/err.h \ + src/u8c/errlock.h \ + src/u8c/seterr.h \ + src/u8c/stat.h OBJS = $(SRCS:.c=.o) LIB = libu8c.so $(LIB): $(OBJS) $(CC) $(LDFLAGS) $^ -o $@ -$(OBJS): $(HDRS) -.PHONY: clean +$(OBJS): $(HDRS) $(HDRS_PRIV) +.PHONY: clean install purge runtest uninstall clean: - rm $(OBJS) -.PHONY: purge -purge: - rm $(LIB) $(OBJS) -.PHONY: install + rm --force $(OBJS) install: $(LIB) mkdir --parents $(DESTDIR)/include/u8c mkdir --parents $(DESTDIR)/lib install --mode=444 $(HDRS) $(DESTDIR)/include/u8c install --mode=555 $(LIB) $(DESTDIR)/lib -.PHONY: uninstall +purge: + rm --force test txttolit $(LIB) $(OBJS) +runtest: test + export LD_LIBRARY_PATH=$(CURDIR) && ./$^ +test: $(LIB) test.c + $(CC) $(CFLAGS0) +txttolit: $(LIB) txttolit.c + $(CC) $(CFLAGS0) + export LD_LIBRARY_PATH=$(CURDIR) && ./$@ uninstall: rm --force --recursive $(DESTDIR)/include/u8c/ rm --force --recursive $(DESTDIR)/lib/$(LIB) diff --git a/PKGBUILD b/PKGBUILD deleted file mode 100644 index 2e258d5..0000000 --- a/PKGBUILD +++ /dev/null @@ -1,19 +0,0 @@ -# Maintainer: Gabriel Jensen -pkgname=u8c -pkgver=1.0.0 -pkgrel=1 -pkgdesc="C library for encoding, decoding, and printing UTF-8 bytes." -arch=("any") -url="https://mandelbrot.dk/delta/u8c" -license=("AGPL3") -makedepends=("git") -source=("git+https://mandelbrot.dk/delta/u8c.git") -sha512sums=("SKIP") -build() { - cd "$srcdir/$pkgname" - make -j$(nproc) -} -package() { - cd "$srcdir/$pkgname" - make DESTDIR="$pkgdir/usr" install -} @@ -1,6 +1,6 @@ # u8c -[*u8c*](https://mandelbrot.dk/delta/u8c) is a free and open-source C-based library for transforming Unicode codepoints to and from UTF-8 bytes. +[*u8c*](https://mandelbrot.dk/delta/u8c) is a free and open-source C-based library for transforming Unicode codepoints, as well as encoding them into UTF-8, even on implementations that use a different 32 bit encoding. ## Copyright & License diff --git a/changelog.md b/changelog.md index 3ce2ecc..1a61bd7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,25 @@ +# 2 + +* Move PKGBUILD to seperate project. +* Create a *master* header that includes every other header. +* Create `size_t` constant macro. +* Add colour to text formatting. +* Specify what file to print to in `u8c_print`. +* Add C++ compatibility to headers. +* Add functions for initialising and ending *u8c*. +* Add dedicated function for text formatting (altough not working at the moment); `u8c_fmt`. +* Remove `u8c_free`. +* Improve error handling in the form of error messages (which can be retrieved by the programmer via `u8c_geterr`). +* Split `u8c_print` into two functions: `u8c_print` and `u8c_println`. +* Break the UTF-8 decoder somehow. +* Add compile-time option to be thread-safe (requiring C11 threads if enabled). +* Add function for copying UTF-32; `u8c_u32cp`. +* Add function for getting the size of an UTF-32 array; `u8c_u32sz`. +* Add `va_list` alternatives to `u8c_fmt` and `u8c_print`; `u8c_vfmt` and `u8c_vprint`. +* Add test-program (run via `make runtest`). +* Add program to make human-readable UTF-32 strings machine-readable. +* Turn `u8c_ver` into a compile-time macro. + # 1 * Fix Makefile compiling *u8c.so* instead of *libu8c.so*. diff --git a/include/u8c.h b/include/u8c.h new file mode 100644 index 0000000..8a11dd5 --- /dev/null +++ b/include/u8c.h @@ -0,0 +1,36 @@ +/* + 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/>. +*/ +/* Import this header to declare every single thing from u8c. */ +/* Expect long compile time. */ +# include <u8c/col.h> +# include <u8c/dbgprint.h> +# include <u8c/debug.h> +# include <u8c/end.h> +# include <u8c/fmt.h> +# include <u8c/fmttyp.h> +# include <u8c/geterr.h> +# include <u8c/init.h> +# include <u8c/print.h> +# include <u8c/println.h> +# include <u8c/SIZE_C.h> +# include <u8c/thrdsafe.h> +# include <u8c/u32cp.h> +# include <u8c/u32sz.h> +# include <u8c/u8dec.h> +# include <u8c/u8enc.h> +# include <u8c/ver.h> +# include <u8c/vfmt.h> +# include <u8c/vprint.h> diff --git a/include/u8c/SIZE_C.h b/include/u8c/SIZE_C.h new file mode 100644 index 0000000..7c9d1a9 --- /dev/null +++ b/include/u8c/SIZE_C.h @@ -0,0 +1,44 @@ +/* + 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/>. +*/ +/* Size constant */ +# if !defined SIZE_C +# include <limits.h> +# include <stdint.h> +# if SIZE_MAX == USHRT_MAX +# if defined(__cplusplus) +/* C++ : Use variable initialisation. */ +# define SIZE_C(val) (unsigned short{val}) +# else +/* C : Use compound literal. */ +# define SIZE_C(val) ((unsigned short){val}) +# endif +# elif SIZE_MAX == UINT_MAX +# define SIZE_C(val) val +# elif SIZE_MAX == ULONG_MAX +# define SIZE_C(val) val ## ul +# elif SIZE_MAX == ULLONG_MAX +# define SIZE_C(val) val ## ull +# elif SIZE_MAX == UINTMAX_MAX +# define SIZE_C(val) UINTMAX_C(val) +# else +/* Cannot match width; construct new element of type "size_t" */ +# if defined(__cplusplus) +# define SIZE_C(val) (std::size_t{val}) +# else +# define SIZE_C(val) ((size_t){val}) +# endif +# endif +# endif diff --git a/include/u8c/col.h b/include/u8c/col.h new file mode 100644 index 0000000..54a2b4e --- /dev/null +++ b/include/u8c/col.h @@ -0,0 +1,35 @@ +/* + 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/>. +*/ +/* Colour */ +# if !defined(u8c_sym_col) +# define u8c_sym_col +# 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)) +# endif diff --git a/include/u8c/dbgprint.h b/include/u8c/dbgprint.h index 3f4afaf..57cb219 100644 --- a/include/u8c/dbgprint.h +++ b/include/u8c/dbgprint.h @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,13 +13,18 @@ If not, see <https://www.gnu.org/licenses/>. */ -# if !defined(u8c_sym_dbgprint) -# define u8c_sym_dbgprint +/* Debug print */ +# if !defined(u8c_dbgprint) # if defined(NDEBUG) -# define u8c_dbgprint(...) +# if defined(__cplusplus) +# define u8c_dbgprint(...) static_cast<void>(0x0); +# else +# define u8c_dbgprint(...) ((void)0x0) +# endif # else # include <u8c/print.h> # include <stdint.h> -# define u8c_dbgprint(...) { u8c_print(__VA_ARGS__); } +# include <stdio.h> +# define u8c_dbgprint(...) u8c_print(stderr,__VA_ARGS__) # endif # endif diff --git a/include/u8c/debug.h b/include/u8c/debug.h index 38c00b0..3bd2dfd 100644 --- a/include/u8c/debug.h +++ b/include/u8c/debug.h @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,13 +13,15 @@ If not, see <https://www.gnu.org/licenses/>. */ +/* Debug */ # if !defined(u8c_sym_debug) # define u8c_sym_debug # include <stdint.h> -uint_least8_t const inline u8c_debug = -# if defined(NDEBUG) - 0x0; -# else - 0x1; +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t const u8c_debug; +# if defined(__cplusplus) +} # endif # endif diff --git a/include/u8c/end.h b/include/u8c/end.h new file mode 100644 index 0000000..1322496 --- /dev/null +++ b/include/u8c/end.h @@ -0,0 +1,27 @@ +/* + 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/>. +*/ +/* End */ +# if !defined(u8c_sym_end) +# define u8c_sym_end +# include <stdint.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_end(void); +# if defined(__cplusplus) +} +# endif +# endif diff --git a/include/u8c/fmt.h b/include/u8c/fmt.h new file mode 100644 index 0000000..262c3dc --- /dev/null +++ b/include/u8c/fmt.h @@ -0,0 +1,28 @@ +/* + 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/>. +*/ +/* Format */ +# if !defined(u8c_sym_fmt) +# define u8c_sym_fmt +# include <stddef.h> +# include <stdint.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_fmt(size_t * outstrsz,uint_least32_t * * outstr,uint_least32_t * instr,...); +# if defined(__cplusplus) +} +# endif +# endif diff --git a/include/u8c/fmttyp.h b/include/u8c/fmttyp.h index b2d79ea..e81e774 100644 --- a/include/u8c/fmttyp.h +++ b/include/u8c/fmttyp.h @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,12 +13,17 @@ If not, see <https://www.gnu.org/licenses/>. */ +/* Format type */ # if !defined(u8c_sym_fmttyp) # define u8c_sym_fmttyp enum u8c_fmttyp { - u8c_fmttyp_chr, - u8c_fmttyp_int, - u8c_fmttyp_str, - u8c_fmttyp_uint, + u8c_fmttyp_bgcol, /* Background colour */ + u8c_fmttyp_bgcol0, /* Background colour #0 */ + u8c_fmttyp_chr, /* Character */ + u8c_fmttyp_fgcol, /* Foreground colour */ + u8c_fmttyp_fgcol0, /* Foreground colour #0 */ + u8c_fmttyp_int, /* Integer */ + u8c_fmttyp_str, /* String */ + u8c_fmttyp_uint, /* Unsigned integer */ }; # endif diff --git a/include/u8c/geterr.h b/include/u8c/geterr.h new file mode 100644 index 0000000..279f1fb --- /dev/null +++ b/include/u8c/geterr.h @@ -0,0 +1,27 @@ +/* + 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/>. +*/ +/* Get error */ +# if !defined(u8c_sym_geterr) +# define u8c_sym_geterr +# include <stdint.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_geterr(size_t * sz,uint_least32_t * * u32); +# if defined(__cplusplus) +} +# endif +# endif diff --git a/include/u8c/init.h b/include/u8c/init.h new file mode 100644 index 0000000..823c1fb --- /dev/null +++ b/include/u8c/init.h @@ -0,0 +1,27 @@ +/* + 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/>. +*/ +/* Initialise */ +# if !defined(u8c_sym_init) +# define u8c_sym_init +# include <stdint.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_init(void); +# if defined(__cplusplus) +} +# endif +# endif diff --git a/include/u8c/print.h b/include/u8c/print.h index 0e52cf1..acbda08 100644 --- a/include/u8c/print.h +++ b/include/u8c/print.h @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,8 +13,16 @@ If not, see <https://www.gnu.org/licenses/>. */ +/* Print */ # if !defined(u8c_sym_print) # define u8c_sym_print # include <stdint.h> -extern uint_least8_t u8c_print(uint_least32_t * str,...); +# include <stdio.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_print(FILE * fp,uint_least32_t * msg,...); +# if defined(__cplusplus) +} +# endif # endif diff --git a/include/u8c/println.h b/include/u8c/println.h new file mode 100644 index 0000000..10ebff3 --- /dev/null +++ b/include/u8c/println.h @@ -0,0 +1,28 @@ +/* + 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/>. +*/ +/* Print line */ +# if !defined(u8c_sym_println) +# define u8c_sym_println +# include <stdint.h> +# include <stdio.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_println(FILE * fp,uint_least32_t * msg,...); +# if defined(__cplusplus) +} +# endif +# endif diff --git a/include/u8c/thrdsafe.h b/include/u8c/thrdsafe.h new file mode 100644 index 0000000..1de6a31 --- /dev/null +++ b/include/u8c/thrdsafe.h @@ -0,0 +1,27 @@ +/* + 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/>. +*/ +/* Thread-safe */ +# if !defined(u8c_sym_thrdsafe) +# define u8c_sym_thrdsafe +# include <stdint.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t const u8c_thrdsafe; +# if defined(__cplusplus) +} +# endif +# endif diff --git a/include/u8c/u32cp.h b/include/u8c/u32cp.h new file mode 100644 index 0000000..b0ca35f --- /dev/null +++ b/include/u8c/u32cp.h @@ -0,0 +1,28 @@ +/* + 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 copy */ +# if !defined(luma_sym_u32cp) +# define luma_sym_u32cp +# include <stddef.h> +# include <stdint.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_u32cp(size_t * sz,uint_least32_t * * out,uint_least32_t * in); +# if defined(__cplusplus) +} +# endif +# endif diff --git a/include/u8c/u32sz.h b/include/u8c/u32sz.h new file mode 100644 index 0000000..28ef2e4 --- /dev/null +++ b/include/u8c/u32sz.h @@ -0,0 +1,28 @@ +/* + 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 size */ +# if !defined(u8c_sym_u32sz) +# define u8c_sym_u32sz +# include <stddef.h> +# include <stdint.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_u32sz(size_t * sz,uint_least32_t * u32); +# if defined(__cplusplus) +} +# endif +# endif diff --git a/include/u8c/u8dec.h b/include/u8c/u8dec.h index 07c0e27..8ebf64e 100644 --- a/include/u8c/u8dec.h +++ b/include/u8c/u8dec.h @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,9 +13,16 @@ If not, see <https://www.gnu.org/licenses/>. */ -# if !defined(u8c_sym_u8dec) -# define u8c_sym_u8dec +/* UTF-8 decode */ +# if !defined(u8c_sym_dec) +# define u8c_sym_dec # include <stddef.h> # include <stdint.h> -extern uint_least8_t u8c_u8dec(uint_least8_t * utf,size_t * codepssz,uint_least32_t * * codeps); +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_u8dec(size_t * outsz,uint_least32_t * * out,uint_least8_t * in); +# if defined(__cplusplus) +} +# endif # endif diff --git a/include/u8c/u8enc.h b/include/u8c/u8enc.h index 6083c2a..f4bdfa5 100644 --- a/include/u8c/u8enc.h +++ b/include/u8c/u8enc.h @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,9 +13,16 @@ If not, see <https://www.gnu.org/licenses/>. */ -# if !defined(u8c_sym_u8enc) -# define u8c_sym_u8enc +/* UTF-8 encode */ +# if !defined(u8c_sym_enc) +# define u8c_sym_enc # include <stddef.h> # include <stdint.h> -extern uint_least8_t u8c_u8enc(uint_least32_t * codeps,size_t * utfsz,uint_least8_t * * utf); +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_u8enc(size_t * sz,uint_least8_t * * out,uint_least32_t * in); +# if defined(__cplusplus) +} +# endif # endif diff --git a/include/u8c/ver.h b/include/u8c/ver.h index 3e8af37..3c07ec6 100644 --- a/include/u8c/ver.h +++ b/include/u8c/ver.h @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,8 +13,8 @@ If not, see <https://www.gnu.org/licenses/>. */ -# if !defined(u8c_sym_ver) -# define u8c_sym_ver +/* Version */ +# if !defined(u8c_ver) # include <stdint.h> -uint_least64_t const inline u8c_debug = 0x1; +# define u8c_ver (UINT64_C(0x2)) # endif diff --git a/include/u8c/vfmt.h b/include/u8c/vfmt.h new file mode 100644 index 0000000..c12e251 --- /dev/null +++ b/include/u8c/vfmt.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/>. +*/ +/* Variadic format */ +# if !defined(u8c_sym_vfmt) +# define u8c_sym_vfmt +# include <stdarg.h> +# include <stddef.h> +# include <stdint.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_vfmt(size_t * outsz,uint_least32_t * * out,uint_least32_t * in,va_list args); +# if defined(__cplusplus) +} +# endif +# endif diff --git a/include/u8c/vprint.h b/include/u8c/vprint.h new file mode 100644 index 0000000..154aef6 --- /dev/null +++ b/include/u8c/vprint.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/>. +*/ +/* Variadic print */ +# if !defined(u8c_sym_vprint) +# define u8c_sym_vprint +# include <stdarg.h> +# include <stdint.h> +# include <stdio.h> +# if defined(__cplusplus) +extern "C" { +# endif +extern uint_least8_t u8c_vprint(FILE * fp,uint_least32_t * msg,va_list args); +# if defined(__cplusplus) +} +# endif +# endif diff --git a/src/u8c/debug.c b/src/u8c/debug.c new file mode 100644 index 0000000..eb926eb --- /dev/null +++ b/src/u8c/debug.c @@ -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/>. +*/ +# include <stdint.h> +# include <u8c/debug.h> +uint_least8_t const u8c_debug = +# if defined(NDEBUG) + UINT8_C(0x0); +# else + UINT8_C(0x1); +# endif diff --git a/src/u8c/end.c b/src/u8c/end.c new file mode 100644 index 0000000..b4e79f2 --- /dev/null +++ b/src/u8c/end.c @@ -0,0 +1,36 @@ +/* + 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 "err.h" +# include "errlock.h" +# include "stat.h" +# include <stdint.h> +# include <stdlib.h> +# include <u8c/end.h> +# include <u8c/print.h> +# if defined(u8c_bethrdsafe) +# include <threads.h> +# endif +uint_least8_t u8c_end(void) { + if(u8c_stat > UINT8_C(0x0)) { + return UINT8_C(0x0); + } +# if defined(u8c_bethrdsafe) + mtx_destroy(&u8c_errlock); +# endif + free(u8c_err); + u8c_stat = UINT8_C(0x1); + return UINT8_C(0x0); +} diff --git a/src/u8c/free.c b/src/u8c/err.c index f58f667..6c7a940 100644 --- a/src/u8c/free.c +++ b/src/u8c/err.c @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,10 +13,7 @@ If not, see <https://www.gnu.org/licenses/>. */ -# include <u8c/free.h> +# include "err.h" +# include <stddef.h> # include <stdint.h> -# include <stdlib.h> -uint_least8_t u8c_free(void * ptr) { - free(ptr); - return 0x0; -} +uint_least32_t * u8c_err = NULL; diff --git a/include/u8c/free.h b/src/u8c/err.h index 573089e..895710d 100644 --- a/include/u8c/free.h +++ b/src/u8c/err.h @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,8 +13,8 @@ If not, see <https://www.gnu.org/licenses/>. */ -# if !defined(u8c_sym_free) -# define u8c_sym_free +# if !defined(u8c_sym_err) +# define u8c_sym_err # include <stdint.h> -extern uint_least8_t u8c_free(void * ptr); +extern uint_least32_t * u8c_err; # endif diff --git a/src/u8c/errlock.c b/src/u8c/errlock.c new file mode 100644 index 0000000..b63a435 --- /dev/null +++ b/src/u8c/errlock.c @@ -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/>. +*/ +# include "errlock.h" +# if defined(u8c_bethrdsafe) +# include <threads.h> +mtx_t u8c_errlock; +# endif diff --git a/src/u8c/errlock.h b/src/u8c/errlock.h new file mode 100644 index 0000000..d1d380c --- /dev/null +++ b/src/u8c/errlock.h @@ -0,0 +1,22 @@ +/* + 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_errlock) +# define u8c_sym_errlock +# if defined(u8c_bethrdsafe) +# include <threads.h> +extern mtx_t u8c_errlock; +# endif +# endif diff --git a/src/u8c/fmt.c b/src/u8c/fmt.c new file mode 100644 index 0000000..dabf376 --- /dev/null +++ b/src/u8c/fmt.c @@ -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/>. +*/ +# include <u8c/fmt.h> +# include <u8c/fmttyp.h> +# include <u8c/u8enc.h> +# include <u8c/vfmt.h> +# include <stdarg.h> +# include <stddef.h> +# include <stdint.h> +uint_least8_t u8c_fmt(size_t * _outsz,uint_least32_t * * _out,uint_least32_t * _in,...) { + va_list args; + va_start(args,_in); + uint_least8_t val = u8c_vfmt(_outsz,_out,_in,args); + va_end(args); + return val; +} diff --git a/src/u8c/geterr.c b/src/u8c/geterr.c new file mode 100644 index 0000000..113281e --- /dev/null +++ b/src/u8c/geterr.c @@ -0,0 +1,31 @@ +/* + 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 "err.h" +# include "errlock.h" +# include <stdint.h> +# include <stdlib.h> +# include <u8c/u32cp.h> +# include <u8c/geterr.h> +uint_least8_t u8c_geterr(size_t * _sz,uint_least32_t * * _u32) { + # if defined(u8c_bethrdsafe) + mtx_lock(&u8c_errlock); + # endif + u8c_u32cp(_sz,_u32,u8c_err); + # if defined(u8c_bethrdsafe) + mtx_unlock(&u8c_errlock); + # endif + return UINT8_C(0x0); + } diff --git a/src/u8c/init.c b/src/u8c/init.c new file mode 100644 index 0000000..0f752ce --- /dev/null +++ b/src/u8c/init.c @@ -0,0 +1,40 @@ +/* + 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 "err.h" +# include "errlock.h" +# include "stat.h" +# include <assert.h> +# include <stdint.h> +# include <stdlib.h> +# include <u8c/end.h> +# include <u8c/init.h> +# include <u8c/SIZE_C.h> +# include <u8c/u32cp.h> +# if defined(u8c_bethrdsafe) +# include <threads.h> +# endif +extern uint_least8_t u8c_init(void) { +# if defined(u8c_bethrdsafe) + if(mtx_init(&u8c_errlock,mtx_plain) == thrd_error) { + return UINT8_C(0x2); + } +# endif + /* Set default error message: */ + u8c_u32cp(NULL,&u8c_err,(uint_least32_t[]){UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x63),UINT32_C(0x5F),UINT32_C(0x69),UINT32_C(0x6E),UINT32_C(0x69),UINT32_C(0x74),UINT32_C(0x3A),UINT32_C(0x20),UINT32_C(0x44),UINT32_C(0x65),UINT32_C(0x66),UINT32_C(0x61),UINT32_C(0x75),UINT32_C(0x6C),UINT32_C(0x74),UINT32_C(0x20),UINT32_C(0x65),UINT32_C(0x72),UINT32_C(0x72),UINT32_C(0x6F),UINT32_C(0x72),UINT32_C(0x20),UINT32_C(0x6D),UINT32_C(0x65),UINT32_C(0x73),UINT32_C(0x73),UINT32_C(0x61),UINT32_C(0x67),UINT32_C(0x65),UINT32_C(0x2E),UINT32_C(0x0),}); /* u8c_init: Default error message. */ + /* Set status: */ + u8c_stat = UINT8_C(0x0); + return UINT8_C(0x0); +} diff --git a/src/u8c/print.c b/src/u8c/print.c index 741d25a..5308f18 100644 --- a/src/u8c/print.c +++ b/src/u8c/print.c @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,84 +13,14 @@ If not, see <https://www.gnu.org/licenses/>. */ -# include <u8c/fmttyp.h> -# include <u8c/u8enc.h> # include <stdarg.h> # include <stdint.h> -# include <stdio.h> -# include <stdlib.h> -uint_least8_t u8c_print(uint_least32_t * msg,...) { +# include <u8c/print.h> +# include <u8c/vprint.h> +uint_least8_t u8c_print(FILE * _fp,uint_least32_t * _msg,...) { va_list args; - va_start(args,msg); - for(size_t n = (size_t){0x0};;n += (size_t){0x1}) { - if(msg[n] == (uint_least32_t){0x0}) { - fwrite(&(uint_least8_t){0xA},(size_t){0x1},(size_t){0x1},stdout); - break; - } - if(msg[n] == (uint_least32_t){0xFFFD}) { - enum u8c_fmttyp fmttyp = va_arg(args,enum u8c_fmttyp); - switch(fmttyp) { - case u8c_fmttyp_chr: - { - uint_least32_t const chr = va_arg(args,uint_least32_t); - if(chr == (uint_least32_t){0x0}) { - continue; - } - size_t strsz = (size_t){0x0}; - uint_least8_t * str = NULL; - u8c_u8enc((uint_least32_t[]){chr,0x0},&strsz,&str); - fwrite(str,(size_t){0x1},strsz - (size_t){0x1},stdout); - free(str); - break; - } - case u8c_fmttyp_int: - { - int_least64_t n = va_arg(args,int_least64_t); - if(n < 0x0) { - size_t chrsz = (size_t){0x0}; - uint_least8_t * chr = NULL; - u8c_u8enc((uint_least32_t[]){0x2212,0x0},&chrsz,&chr); - fwrite(chr,(size_t){0x1},chrsz - (size_t){0x1},stdout); - free(chr); - } - for(;n != 0x0;n /= (int_least64_t){0xB}) { - - } - break; - } - case u8c_fmttyp_str: - { - size_t strsz = (size_t){0x0}; - uint_least8_t * str = NULL; - u8c_u8enc(va_arg(args,uint_least32_t *),&strsz,&str); - fwrite(str,(size_t){0x1},strsz - (size_t){0x1},stdout); - free((void *)str); - break; - } - case u8c_fmttyp_uint: - { - break; - } - } - continue; - } - size_t chrsz = (size_t){0x0}; - uint_least8_t * chr = NULL; - u8c_u8enc((uint_least32_t[]){msg[n],0x0,0x0},&chrsz,&chr); - fwrite(chr,(size_t){0x1},chrsz - (size_t){0x1},stdout); - free((void *)chr); - } + va_start(args,_msg); + uint_least8_t val = u8c_vprint(_fp,_msg,args); va_end(args); - return 0x0; + return val; } -/* - ####################### - # # - # ## ## ### # # ### # - # # # # # # ### # # - # ## ## # ### # # - # # # # # ### # # - # # # # ### # # # # - # # - ####################### -*/ diff --git a/src/u8c/println.c b/src/u8c/println.c new file mode 100644 index 0000000..1b1830d --- /dev/null +++ b/src/u8c/println.c @@ -0,0 +1,35 @@ +/* + 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 "seterr.h" +# include <stdarg.h> +# include <stdint.h> +# include <stdio.h> +# include <u8c/println.h> +# include <u8c/SIZE_C.h> +# include <u8c/vprint.h> +uint_least8_t u8c_println(FILE * _fp,uint_least32_t * _msg,...) { + va_list args; + va_start(args,_msg); + if(u8c_vprint(_fp,_msg,args)) { + return UINT8_C(0x1); + } + 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. */ + return UINT8_C(0x0); + } + va_end(args); + return UINT8_C(0x0); +} diff --git a/src/u8c/seterr.c b/src/u8c/seterr.c new file mode 100644 index 0000000..4692348 --- /dev/null +++ b/src/u8c/seterr.c @@ -0,0 +1,39 @@ +/* + 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 "err.h" +# include "errlock.h" +# include "seterr.h" +# include <assert.h> +# include <stdint.h> +# include <stdlib.h> +# include <u8c/dbgprint.h> +# include <u8c/u32cp.h> +# if defined(u8c_bethrdsafe) +# include <threads.h> +# endif +uint_least8_t u8c_seterr(uint_least32_t * _msg) { + assert(_msg != NULL); + u8c_dbgprint(_msg); +# if defined(u8c_bethrdsafe) + mtx_lock(&u8c_errlock); +# endif + free(u8c_err); + u8c_u32cp(NULL,&u8c_err,_msg); +# if defined(u8c_bethrdsafe) + mtx_unlock(&u8c_errlock); +# endif + return UINT8_C(0x0); +} diff --git a/src/u8c/seterr.h b/src/u8c/seterr.h new file mode 100644 index 0000000..c7832c2 --- /dev/null +++ b/src/u8c/seterr.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_seterr) +# define u8c_sym_seterr +# include <stdint.h> +extern uint_least8_t u8c_seterr(uint_least32_t * msg); +# endif diff --git a/src/u8c/stat.c b/src/u8c/stat.c new file mode 100644 index 0000000..63214ec --- /dev/null +++ b/src/u8c/stat.c @@ -0,0 +1,22 @@ +/* + 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 "stat.h" +# include <stdint.h> +/* + 0x0 = Finished. + 0x1 = Initialised. +*/ +uint_least8_t u8c_stat = UINT8_C(0x0); diff --git a/src/u8c/stat.h b/src/u8c/stat.h new file mode 100644 index 0000000..92b2063 --- /dev/null +++ b/src/u8c/stat.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_done) +# define u8c_sym_done +# include <stdint.h> +extern uint_least8_t u8c_stat; +# endif diff --git a/src/u8c/thrdsafe.c b/src/u8c/thrdsafe.c new file mode 100644 index 0000000..3cb4c4d --- /dev/null +++ b/src/u8c/thrdsafe.c @@ -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/>. +*/ +# include <stdint.h> +# include <u8c/thrdsafe.h> +uint_least8_t const u8c_thrdsafe = +# if defined(u8c_bethrdsafe) + UINT8_C(0x1); +# else + UINT8_C(0x0); +# endif diff --git a/src/u8c/u32cp.c b/src/u8c/u32cp.c new file mode 100644 index 0000000..2462d85 --- /dev/null +++ b/src/u8c/u32cp.c @@ -0,0 +1,40 @@ +/* + 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 "seterr.h" +# include <assert.h> +# include <stddef.h> +# include <stdint.h> +# include <stdlib.h> +# include <u8c/SIZE_C.h> +# include <u8c/u32cp.h> +# include <u8c/u32sz.h> +uint_least8_t u8c_u32cp(size_t * _sz,uint_least32_t * * _out,uint_least32_t * _in) { + assert(_in != NULL); + size_t insz = SIZE_C(0x0); + u8c_u32sz(&insz,_in); + assert(insz > SIZE_C(0x0)); + if(_sz != NULL) { + *_sz = insz; + } + if((*_out = calloc(sizeof(uint_least32_t),insz)) == NULL) { + 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(0x70),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(0x61),UINT32_C(0x6C),UINT32_C(0x6C),UINT32_C(0x6F),UINT32_C(0x63),UINT32_C(0x61),UINT32_C(0x74),UINT32_C(0x65),UINT32_C(0x20),UINT32_C(0x72),UINT32_C(0x65),UINT32_C(0x73),UINT32_C(0x6F),UINT32_C(0x75),UINT32_C(0x72),UINT32_C(0x63),UINT32_C(0x65),UINT32_C(0x73),UINT32_C(0x2E),UINT32_C(0x0),}); /* u8c_u32cp: Unable to allocate resources. */ + return UINT8_C(0x1); + } + for(size_t n = SIZE_C(0x0);n < insz;n += SIZE_C(0x1)) { + (*_out)[n] = _in[n]; + } + return UINT8_C(0x0); +} diff --git a/src/u8c/u32sz.c b/src/u8c/u32sz.c new file mode 100644 index 0000000..614557c --- /dev/null +++ b/src/u8c/u32sz.c @@ -0,0 +1,32 @@ +/* + 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 <stddef.h> +# include <stdint.h> +# include <stdio.h> +# include <u8c/SIZE_C.h> +# include <u8c/u32sz.h> +uint_least8_t u8c_u32sz(size_t * _sz,uint_least32_t * _u32) { + assert(_sz != NULL); + assert(_u32 != NULL); + for(size_t n = SIZE_C(0x0);n <= SIZE_MAX;n += SIZE_C(0x1)) { + if(_u32[n] == UINT32_C(0x0)) { + *_sz = n += SIZE_C(0x1); + return UINT8_C(0x0); + } + } + return UINT8_C(0x1); +} diff --git a/src/u8c/u8dec.c b/src/u8c/u8dec.c index 60f4c3d..d7ddb05 100644 --- a/src/u8c/u8dec.c +++ b/src/u8c/u8dec.c @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,83 +13,83 @@ If not, see <https://www.gnu.org/licenses/>. */ -# include <u8c/dbgprint.h> -# include <u8c/u8dec.h> +# include "seterr.h" +# include <assert.h> # include <stdint.h> -# include <stdio.h> # include <stdlib.h> -uint_least8_t u8c_u8dec(uint_least8_t * utf,size_t * codepssz,uint_least32_t * * codeps) { - size_t insz = (size_t){0x0}; - size_t outsz = (size_t){0x0}; - for(size_t n = (size_t){0x0};;n += (size_t){0x1}) { // First pass: get size of input array and determine size of output array. - outsz += (size_t){0x1}; - if(utf[n] == (uint_least8_t){0x0}) { // Null-terminator. +# include <u8c/dbgprint.h> +# include <u8c/u8dec.h> +# include <u8c/SIZE_C.h> +uint_least8_t u8c_u8dec(size_t * _outsz,uint_least32_t * * _out,uint_least8_t * _in) { + assert(_in != NULL); + size_t insz = SIZE_C(0x0); + size_t outsz = SIZE_C(0x0); + for(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. */ + outsz += SIZE_C(0x1); + if(_in[n] == UINT8_C(0x0)) { /* Null-terminator: end of string has been reached. */ insz = n; - break; + goto nottoobig; + } + if(_in[n] >= UINT8_C(0xF8)) { /* Too big. */ + u8c_seterr((uint_least32_t[]){UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x63),UINT32_C(0x5F),UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x64),UINT32_C(0x65),UINT32_C(0x63),UINT32_C(0x3A),UINT32_C(0x20),UINT32_C(0x43),UINT32_C(0x68),UINT32_C(0x61),UINT32_C(0x72),UINT32_C(0x61),UINT32_C(0x63),UINT32_C(0x74),UINT32_C(0x65),UINT32_C(0x72),UINT32_C(0x20),UINT32_C(0x6F),UINT32_C(0x75),UINT32_C(0x74),UINT32_C(0x20),UINT32_C(0x6F),UINT32_C(0x66),UINT32_C(0x20),UINT32_C(0x72),UINT32_C(0x61),UINT32_C(0x6E),UINT32_C(0x67),UINT32_C(0x65),UINT32_C(0x20),UINT32_C(0x28),UINT32_C(0x74),UINT32_C(0x6F),UINT32_C(0x6F),UINT32_C(0x20),UINT32_C(0x62),UINT32_C(0x69),UINT32_C(0x67),UINT32_C(0x29),UINT32_C(0x2E),UINT32_C(0x0),}); /* u8c_u8dec: Character out of range (too big). */ + return UINT8_C(0x1); } - if(utf[n] >= (uint_least8_t){0xF0}) { // Four byte. - n += (size_t){0x4}; + if(_in[n] >= UINT8_C(0xF0)) { /* Four byte. */ + n += SIZE_C(0x4); continue; } - if(utf[n] >= (uint_least8_t){0xE0}) { // Three bytes. - n += (size_t){0x3}; + if(_in[n] >= UINT8_C(0xE0)) { /* Three bytes. */ + n += SIZE_C(0x3); continue; } - if(utf[n] >= (uint_least8_t){0xC0}) { // Two bytes. - n += (size_t){0x2}; + if(_in[n] >= UINT8_C(0xC0)) { /* Two bytes. */ + n += SIZE_C(0x2); continue; } + /* One byte. */ + n += SIZE_C(0x1); } - if(codepssz != NULL) { - *codepssz = outsz; + u8c_seterr((uint_least32_t[]){UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x63),UINT32_C(0x5F),UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x64),UINT32_C(0x65),UINT32_C(0x63),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_u8dec: Unterminated input. */ + return UINT8_C(0x1); +nottoobig:; + if(_outsz != NULL) { + *_outsz = outsz; } - *codeps = malloc(outsz); - (*codeps)[outsz - (size_t){0x1}] = (uint_least32_t){0x0}; // Create null-terminator on output array. - for(size_t n = (size_t){0x0}, outn = (size_t){0x0};n < insz;n += (size_t){0x1},outn += (size_t){0x1}) { // Second pass: decode UTF-8. - uint_least8_t chr = utf[n]; - if(chr >= (uint_least8_t){0xF7}) { // Out of range. - u8c_dbgprint(U"Out of range (in character decoding: byte too big)."); - return 0x1; - } - if(chr >= (uint_least8_t){0xF0}) { // Four byte. - uint_least32_t codep = (uint_least32_t){(chr ^ 0xF0) << 0x12}; - n += (size_t){0x1}; - chr = utf[n]; - codep += (uint_least32_t){(chr ^ 0x80) << 0xC}; - n += (size_t){0x1}; - chr = utf[n]; - codep += (uint_least32_t){(chr ^ 0x80) << 0x6}; - n += (size_t){0x1}; - chr = utf[n]; - codep += (uint_least32_t){(chr ^ 0x80)}; - (*codeps)[outn] = codep; + *_out = calloc(sizeof(uint_least8_t),outsz); + (*_out)[outsz - SIZE_C(0x1)] = (uint_least32_t){0x0}; /* Create null-terminator on output array. */ + for(size_t n = SIZE_C(0x0), outn = SIZE_C(0x0);n < insz;n += SIZE_C(0x1),outn += SIZE_C(0x1)) { /* Second pass: decode UTF-8. */ + if(_in[n] >= UINT8_C(0xF0)) { /* Four byte. */ + uint_least32_t codep = (_in[n] ^ UINT32_C(0xF0)) << UINT32_C(0x12); + n += SIZE_C(0x1); + codep += (_in[n] ^ UINT32_C(0x80)) << UINT32_C(0xC); + n += SIZE_C(0x1); + codep += (_in[n] ^ UINT32_C(0x80)) << UINT32_C(0x6); + n += SIZE_C(0x1); + codep += (uint_least32_t)(_in[n]) ^ SIZE_C(0x80); + (*_out)[outn] = codep; continue; } - if(chr >= (uint_least8_t){0xE0}) { // Three bytes. - uint_least32_t codep = (uint_least32_t){(chr ^ 0xE0) << 0xC}; - n += (size_t){0x1}; - chr = utf[n]; - codep += (uint_least32_t){(chr ^ 0x80) << 0x6}; - n += (size_t){0x1}; - chr = utf[n]; - codep += (uint_least32_t){(chr ^ 0x80)}; - n += (size_t){0x1}; - (*codeps)[outn] = codep; + if(_in[n] >= UINT8_C(0xE0)) { /* Three bytes. */ + uint_least32_t codep = (_in[n] ^ UINT32_C(0xE0)) << UINT32_C(0xC); + n += SIZE_C(0x1); + codep += (_in[n] ^ UINT32_C(0x80)) << UINT32_C(0x6); + n += SIZE_C(0x1); + codep += _in[n] ^ UINT32_C(0x80); + n += SIZE_C(0x1); + (*_out)[outn] = codep; continue; } - if(chr >= (uint_least8_t){0xC0}) { // Two bytes. - uint_least32_t codep = (uint_least32_t){(chr ^ 0xC0) << 0x6}; - n += (size_t){0x1}; - chr = utf[n]; - codep += (uint_least32_t){(chr ^ 0x80)}; - n += (size_t){0x1}; - (*codeps)[outn] = codep; + if(_in[n] >= UINT8_C(0xC0)) { /* Two bytes. */ + uint_least32_t codep = (_in[n] ^ UINT32_C(0xC0)) << UINT32_C(0x6); + n += SIZE_C(0x1); + codep += _in[n] ^ UINT32_C(0x80); + n += SIZE_C(0x1); + (*_out)[outn] = codep; continue; } - // One byte. - uint_least32_t codep = (uint_least32_t){chr}; - (*codeps)[outn] = codep; + /* One byte. */ + (*_out)[outn] = (uint_least32_t)(_in[n]); continue; } - return 0x0; + return UINT8_C(0x0); } diff --git a/src/u8c/u8enc.c b/src/u8c/u8enc.c index 3ea6cdc..f37e9cf 100644 --- a/src/u8c/u8enc.c +++ b/src/u8c/u8enc.c @@ -3,9 +3,9 @@ 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 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. + 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. @@ -13,70 +13,76 @@ If not, see <https://www.gnu.org/licenses/>. */ -# include <u8c/u8enc.h> +# include "seterr.h" +# include <assert.h> # include <stdint.h> -# include <stdio.h> # include <stdlib.h> -uint_least8_t u8c_u8enc(uint_least32_t * codeps,size_t * utfsz,uint_least8_t * * utf) { - size_t sz = (size_t){0x0}; // Size of input array (bytes). - size_t outsz = (size_t){0x0}; // Size of output array /bytes). - for(size_t n = (size_t){0x0};;n += (size_t){0x1}) { // First pass: get size of input array, and determine size of output array. - uint_least32_t codep = codeps[n]; // Current Unicode codepoint. - if(codep == (uint_least32_t){0x0}) { // U+0000 is Null. - sz = n; - break; +# include <u8c/u8enc.h> +# include <u8c/SIZE_C.h> +uint_least8_t u8c_u8enc(size_t * _sz,uint_least8_t * * _out,uint_least32_t * _in) { + assert(_in != NULL); + size_t insz = SIZE_C(0x0); /* Size of input array (bytes). */ + size_t outsz = SIZE_C(0x0); /* Size of output array /bytes). */ + for(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. */ + if(_in[n] == UINT32_C(0x0)) { /* U+0000 is Null. */ + insz = n; + goto nottoobig; } - if(codep >= (uint_least32_t){0x110000}) { // Codepoint out of range. - return 0x1; + if(_in[n] >= UINT32_C(0x110000)) { /* Codepoint out of range. */ + u8c_seterr((uint_least32_t[]){UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x63),UINT32_C(0x5F),UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x65),UINT32_C(0x6E),UINT32_C(0x63),UINT32_C(0x3A),UINT32_C(0x20),UINT32_C(0x43),UINT32_C(0x6F),UINT32_C(0x64),UINT32_C(0x65),UINT32_C(0x70),UINT32_C(0x6F),UINT32_C(0x69),UINT32_C(0x6E),UINT32_C(0x74),UINT32_C(0x20),UINT32_C(0x6F),UINT32_C(0x75),UINT32_C(0x74),UINT32_C(0x20),UINT32_C(0x6F),UINT32_C(0x66),UINT32_C(0x20),UINT32_C(0x72),UINT32_C(0x61),UINT32_C(0x6E),UINT32_C(0x67),UINT32_C(0x65),UINT32_C(0x20),UINT32_C(0x28),UINT32_C(0x74),UINT32_C(0x6F),UINT32_C(0x6F),UINT32_C(0x20),UINT32_C(0x62),UINT32_C(0x69),UINT32_C(0x67),UINT32_C(0x29),UINT32_C(0x2E),UINT32_C(0x0),}); /* u8c_u8enc: Codepoint out of range (too big). */ + return UINT8_C(0x1); } - if(codep >= (uint_least32_t){0x10000}) { // 4 bytes. - outsz += (size_t){0x4}; + if(_in[n] >= UINT32_C(0x10000)) { /* 4 bytes. */ + outsz += SIZE_C(0x4); continue; } - if(codep >= (uint_least32_t){0x800}) { // 3 bytes. - outsz += (size_t){0x3}; + if(_in[n] >= UINT32_C(0x800)) { /* 3 bytes. */ + outsz += SIZE_C(0x3); continue; } - if(codep >= (uint_least32_t){0x80}) { // 2 bytes. - outsz += (size_t){0x2}; + if(_in[n] >= UINT32_C(0x80)) { /* 2 bytes. */ + outsz += SIZE_C(0x2); continue; } - // 1 byte. - outsz += (size_t){0x1}; + /* 1 byte. */ + outsz += SIZE_C(0x1); } - outsz += (size_t){0x1}; // Add space for null-terminator. - if(utfsz != NULL) { - *utfsz = outsz; + u8c_seterr((uint_least32_t[]){UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x63),UINT32_C(0x5F),UINT32_C(0x75),UINT32_C(0x38),UINT32_C(0x65),UINT32_C(0x6E),UINT32_C(0x63),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_u8enc: Unterminated input. */ + return UINT8_C(0x1); +nottoobig:; + outsz += SIZE_C(0x1); /* Reserve space for null-terminator. */ + if(_sz != NULL) { + *_sz = outsz; } - *utf = malloc(outsz); // Allocate space for output array. - (*utf)[outsz - (size_t){0x1}] = (uint_least8_t){0x0}; // Create null-terminator on output array. - for(size_t n = (size_t){0x0}, outn = (size_t){0x0};n < sz;n += (size_t){0x1},outn += (size_t){0x1}) { // Second pass: encode each codepoint into UTF-8. - if(codeps[n] >= 0x10000) { // Four bytes. - (*utf)[outn] = (uint_least8_t){0xF0 + (codeps[n] >> 0x12)}; - outn += (size_t){0x1}; - (*utf)[outn] = (uint_least8_t){0x80 + ((codeps[n] >> 0xC) & 0x3F)}; - outn += (size_t){0x1}; - (*utf)[outn] = (uint_least8_t){0x80 + ((codeps[n] >> 0x6) & 0x3F)}; - outn += (size_t){0x1}; - (*utf)[outn] = (uint_least8_t){0x80 + (codeps[n] & 0x3F)}; + *_out = calloc(sizeof(uint_least8_t),outsz); /* Allocate space for output array. */ + (*_out)[outsz - SIZE_C(0x1)] = UINT8_C(0x0); /* Create null-terminator on output array. */ + for(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. */ + if(_in[n] >= UINT32_C(0x10000)) { // Four bytes. + (*_out)[outn] = UINT8_C(0xF0) + (uint_least8_t)(_in[n] >> UINT32_C(0x12)); + outn += SIZE_C(0x1); + (*_out)[outn] = UINT8_C(0x80) + (uint_least8_t)(_in[n] >> UINT32_C(0xC) & UINT8_C(0x3F)); + outn += SIZE_C(0x1); + (*_out)[outn] = UINT8_C(0x80) + (uint_least8_t)(_in[n] >> UINT32_C(0x6) & UINT8_C(0x3F)); + outn += SIZE_C(0x1); + (*_out)[outn] = UINT8_C(0x80) + (uint_least8_t)(_in[n] & UINT32_C(0x3F)); continue; } - if(codeps[n] >= 0x800) { // Three bytes. - (*utf)[outn] = (uint_least8_t){0xE0 + (codeps[n] >> 0xC)}; - outn += (size_t){0x1}; - (*utf)[outn] = (uint_least8_t){0x80 + ((codeps[n] >> 0x6) & 0x3F)}; - outn += (size_t){0x1}; - (*utf)[outn] = (uint_least8_t){0x80 + (codeps[n] & 0x3F)}; + if(_in[n] >= UINT32_C(0x800)) { /* Three bytes. */ + (*_out)[outn] = UINT8_C(0xE0) + (uint_least8_t)(_in[n] >> UINT32_C(0xC)); + outn += SIZE_C(0x1); + (*_out)[outn] = UINT8_C(0x80) + (uint_least8_t)(_in[n] >> UINT32_C(0x6) & UINT8_C(0x3F)); + outn += SIZE_C(0x1); + (*_out)[outn] = UINT8_C(0x80) + (uint_least8_t)(_in[n] & UINT32_C(0x3F)); continue; } - if(codeps[n] >= 0x80) { // Two bytes. - (*utf)[outn] = (uint_least8_t){0xC0 + (codeps[n] >> 0x6)}; - outn += (size_t){0x1}; - (*utf)[outn] = (uint_least8_t){0x80 + (codeps[n] & 0x3F)}; + if(_in[n] >= UINT32_C(0x80)) { /* Two bytes. */ + (*_out)[outn] = UINT8_C(0xC0) + (uint_least8_t)(_in[n] >> UINT8_C(0x6)); + outn += SIZE_C(0x1); + (*_out)[outn] = UINT8_C(0x80) + (uint_least8_t)(_in[n] & UINT8_C(0x3F)); continue; } - // One byte. - (*utf)[outn] = codeps[n]; + /* One byte. */ + (*_out)[outn] = (uint_least8_t)_in[n]; } - return 0x0; + return UINT8_C(0x0); } diff --git a/src/u8c/vfmt.c b/src/u8c/vfmt.c new file mode 100644 index 0000000..c84aca2 --- /dev/null +++ b/src/u8c/vfmt.c @@ -0,0 +1,30 @@ +/* + 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 <stdarg.h> +# include <stdint.h> +# include <stdio.h> +# include <stdlib.h> +# include <string.h> +# include <u8c/fmttyp.h> +# include <u8c/u32cp.h> +# include <u8c/u8enc.h> +# include <u8c/SIZE_C.h> +# include <u8c/vfmt.h> +uint_least8_t u8c_vfmt(size_t * _outsz,uint_least32_t * * _out,uint_least32_t * _in,va_list _args) { + /* To be added. */ + return u8c_u32cp(_outsz,_out,_in); +} diff --git a/src/u8c/vprint.c b/src/u8c/vprint.c new file mode 100644 index 0000000..fcbafe4 --- /dev/null +++ b/src/u8c/vprint.c @@ -0,0 +1,42 @@ +/* + 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 "seterr.h" +# include <assert.h> +# include <stdarg.h> +# include <stdint.h> +# include <stdio.h> +# include <stdlib.h> +# include <u8c/col.h> +# include <u8c/u8enc.h> +# include <u8c/SIZE_C.h> +# include <u8c/vfmt.h> +# include <u8c/vprint.h> +uint_least8_t u8c_vprint(FILE * _fp,uint_least32_t * _msg,va_list _args) { + assert(_msg != NULL); + uint_least32_t * str0 = NULL; + u8c_vfmt(NULL,&str0,_msg,_args); + size_t str1sz = SIZE_C(0x0); + uint_least8_t * str1 = NULL; + 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((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(0x76),UINT32_C(0x3A),UINT32_C(0x20),UINT32_C(0x66),UINT32_C(0x77),UINT32_C(0x72),UINT32_C(0x69),UINT32_C(0x74),UINT32_C(0x65),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_printv: fwrite: Unable to write to stdout. */ + return UINT8_C(0x1); + } + free(str0); + free(str1); + return UINT8_C(0x0); +} @@ -0,0 +1,86 @@ +# include <inttypes.h> +# include <stdarg.h> +# include <stdint.h> +# include <stdio.h> +# include <stdlib.h> +# include <threads.h> +# include <u8c.h> +static void testmsg(char const * fmt,...) { + va_list args; + va_start(args,fmt); + printf("\n+->\n| \x1b[38:2::169:225:61mTesting\x1b[0m \""); + vprintf(fmt,args); + printf("\"...\n+->\n\n"); + va_end(args); +} +static void testmsgdone(uint_least32_t * num0,uint_least8_t * num1) { + *num0 += (uint_least32_t)(*num1); + printf("\n+->\n| \x1b[38:2::61:225:169mDone\x1b[0m! (\x1b[38:2::225:61:61mErrors\x1b[0m: %" PRIuLEAST32 ")\n+->\n",*num1); + *num1 = UINT8_C(0x0); +} +int main(void) { + u8c_init(); + printf("u8c version: %" PRIXLEAST64 ".\n",u8c_ver); + printf("Debug build: %" PRIXLEAST8 ".\n",u8c_debug); + printf("Thread safe: %" PRIXLEAST8 ".\n",u8c_thrdsafe); + uint_least32_t errcount0 = UINT8_C(0x0); + uint_least8_t errcount1 = UINT8_C(0x0); + testmsg("Error messages"); + { + uint_least32_t * err = NULL; + errcount1 += u8c_geterr(NULL,&err); + errcount1 += u8c_println(stdout,err); + free(err); + } + testmsgdone(&errcount0,&errcount1); + testmsg("UTF-8 encoding/decoding"); + { + uint_least32_t * msg0 = (uint_least32_t[]){UINT32_C(0xA2),UINT32_C(0x2C),UINT32_C(0x939),UINT32_C(0x2C),UINT32_C(0x10348),UINT32_C(0x2C),UINT32_C(0x20AC),UINT32_C(0x2C),UINT32_C(0x218A),UINT32_C(0x2C),UINT32_C(0x1F44B),UINT32_C(0x0)}; + uint_least8_t * msg1 = NULL; + errcount1 += u8c_u8enc(NULL,&msg1,msg0); + printf("Encoded: %s\n",msg1); + errcount1 += u8c_u8dec(NULL,&msg0,msg1); + errcount1 += u8c_u8enc(NULL,&msg1,msg0); + printf("Encoded -> Decoded -> Encoded: %s\n",msg1); + free(msg0); + free(msg1); + } + testmsgdone(&errcount0,&errcount1); + testmsg("Printing (u8c_print)"); + { + errcount1 += u8c_print(stdout,(uint_least32_t[]){UINT32_C(0x48),UINT32_C(0x65),UINT32_C(0x6C),UINT32_C(0x6C),UINT32_C(0x6F),UINT32_C(0x0),}); + errcount1 += u8c_print(stdout,(uint_least32_t[]){UINT32_C(0x20),UINT32_C(0xF0),UINT32_C(0x65),UINT32_C(0x72),UINT32_C(0x65),UINT32_C(0x21),UINT32_C(0xA),UINT32_C(0x0),}); + } + testmsgdone(&errcount0,&errcount1); + testmsg("Printing (u8c_println)"); + { + errcount1 += u8c_println(stdout,(uint_least32_t[]){UINT32_C(0x48),UINT32_C(0x65),UINT32_C(0x6C),UINT32_C(0x6C),UINT32_C(0x6F),UINT32_C(0x0),}); + errcount1 += u8c_println(stdout,(uint_least32_t[]){UINT32_C(0x20),UINT32_C(0xF0),UINT32_C(0x65),UINT32_C(0x72),UINT32_C(0x65),UINT32_C(0x21),UINT32_C(0x0),}); + } + testmsgdone(&errcount0,&errcount1); + testmsg("Text formatting"); + { + errcount1 += u8c_println(stdout,(uint_least32_t[]){UINT32_C(0x54),UINT32_C(0x68),UINT32_C(0x65),UINT32_C(0x20),UINT32_C(0xFFFD),UINT32_C(0x6E),UINT32_C(0x75),UINT32_C(0x6D),UINT32_C(0x62),UINT32_C(0x65),UINT32_C(0x72),UINT32_C(0xFFFD),UINT32_C(0x20),UINT32_C(0x69),UINT32_C(0x73),UINT32_C(0x20),UINT32_C(0xFFFD),UINT32_C(0x2E),UINT32_C(0x0),},u8c_fmttyp_fgcol,u8c_col_mint,u8c_fmttyp_fgcol0,u8c_fmttyp_int,(int_least64_t){-0x10}); + } + testmsgdone(&errcount0,&errcount1); + testmsg("Colour text"); + { + errcount1 += u8c_println(stdout,(uint_least32_t[]){UINT32_C(0xFFFD),UINT32_C(0x72),UINT32_C(0x65),UINT32_C(0x64),UINT32_C(0xFFFD),UINT32_C(0x6F),UINT32_C(0x72),UINT32_C(0x61),UINT32_C(0x6E),UINT32_C(0x67),UINT32_C(0x65),UINT32_C(0xFFFD),UINT32_C(0x79),UINT32_C(0x65),UINT32_C(0x6C),UINT32_C(0x6C),UINT32_C(0x6F),UINT32_C(0x77),UINT32_C(0xFFFD),UINT32_C(0x63),UINT32_C(0x68),UINT32_C(0x61),UINT32_C(0x72),UINT32_C(0x74),UINT32_C(0x72),UINT32_C(0x65),UINT32_C(0x75),UINT32_C(0x73),UINT32_C(0x65),UINT32_C(0xFFFD),UINT32_C(0x67),UINT32_C(0x72),UINT32_C(0x65),UINT32_C(0x65),UINT32_C(0x6E),UINT32_C(0xFFFD),UINT32_C(0x6D),UINT32_C(0x69),UINT32_C(0x6E),UINT32_C(0x74),UINT32_C(0xFFFD),UINT32_C(0x63),UINT32_C(0x79),UINT32_C(0x61),UINT32_C(0x6E),UINT32_C(0xFFFD),UINT32_C(0x61),UINT32_C(0x7A),UINT32_C(0x75),UINT32_C(0x72),UINT32_C(0x65),UINT32_C(0xFFFD),UINT32_C(0x62),UINT32_C(0x6C),UINT32_C(0x75),UINT32_C(0x65),UINT32_C(0xFFFD),UINT32_C(0x76),UINT32_C(0x69),UINT32_C(0x6F),UINT32_C(0x6C),UINT32_C(0x65),UINT32_C(0x74),UINT32_C(0xFFFD),UINT32_C(0x6D),UINT32_C(0x61),UINT32_C(0x67),UINT32_C(0x65),UINT32_C(0x6E),UINT32_C(0x74),UINT32_C(0x61),UINT32_C(0xFFFD),UINT32_C(0x72),UINT32_C(0x6F),UINT32_C(0x73),UINT32_C(0x65),UINT32_C(0xFFFD),UINT32_C(0x0),},u8c_fmttyp_fgcol,u8c_col_red,u8c_fmttyp_fgcol,u8c_col_orange,u8c_fmttyp_fgcol,u8c_col_yellow,u8c_fmttyp_fgcol,u8c_col_chartreuse,u8c_fmttyp_fgcol,u8c_col_green,u8c_fmttyp_fgcol,u8c_col_mint,u8c_fmttyp_fgcol,u8c_col_cyan,u8c_fmttyp_fgcol,u8c_col_azure,u8c_fmttyp_fgcol,u8c_col_blue,u8c_fmttyp_fgcol,u8c_col_violet,u8c_fmttyp_fgcol,u8c_col_magenta,u8c_fmttyp_fgcol,u8c_col_rose,u8c_fmttyp_fgcol0); + } + testmsgdone(&errcount0,&errcount1); + testmsg("Combining characters"); + { + for(uint_least32_t n = UINT32_C(0x300);n <= UINT32_C(0x36F);n += UINT32_C(0x1)) { + errcount1 += u8c_print(stdout,(uint_least32_t[]){UINT32_C(0x41),n,UINT32_C(0x20),UINT32_C(0x0),}); + fflush(stdout); + thrd_sleep(&(struct timespec){.tv_nsec = 0x13DE435},NULL); + } + errcount1 += u8c_print(stdout,(uint_least32_t[]){UINT32_C(0xA),UINT32_C(0x0),}); + } + testmsgdone(&errcount0,&errcount1); + printf("\n"); + printf("Test done!\n"); + printf("Total number of errors: %" PRIuLEAST32 ".\n",errcount0); + u8c_end(); + exit(EXIT_SUCCESS); +} diff --git a/txttolit.c b/txttolit.c new file mode 100644 index 0000000..f22ca69 --- /dev/null +++ b/txttolit.c @@ -0,0 +1,24 @@ +/* + Use this program to convert Unicode message into C-arrays. + Just copy the output and paste it into the source. +*/ +# if !defined(__STDC_UTF_32__) +# error UTF-32 support is needed. +# endif +# include <inttypes.h> +# include <stdio.h> +# include <stdlib.h> +# include <u8c.h> +int main(void) { + u8c_init(); + size_t u32sz = SIZE_C(0x0); + uint_least32_t * u32 = U"u8c_u32cp: Unable to allocate resources."; /* Place string here. */ + u8c_u32sz(&u32sz,u32); + printf("Arrray:\n{"); + for(size_t n = SIZE_C(0x0);n < u32sz;n += SIZE_C(0x1)) { + printf("UINT32_C(0x%" PRIXLEAST32 "),",u32[n]); + } + printf("}\n"); + u8c_end(); + exit(EXIT_SUCCESS); +} |