From 4575f926544db084dc3e3e9574274649ddd1ceb5 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 4 Jul 2026 12:30:04 -0400 Subject: [PATCH] Initial commit --- Makefile | 6 ++++ main.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 Makefile create mode 100644 main.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..787fdff --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +# main.c -> main.o -> main uses implicit rules +all: main + +.PHONY: clean +clean: + rm -f main main.o diff --git a/main.c b/main.c new file mode 100644 index 0000000..fb4f9bd --- /dev/null +++ b/main.c @@ -0,0 +1,83 @@ +#include +#include +#include + +/* The various invalid sequences can be inferred from the table of + * valid ones, + * + * https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-3/#G27506 + * + * Code Points Byte1 Byte2 Byte3 Byte4 + * ---------------------------------------------------------- + * U+0000..U+007F 00..7F + * U+0080..U+07FF C2..DF 80..BF + * U+0800..U+0FFF E0 A0..BF 80..BF + * U+1000..U+CFFF E1..EC 80..BF 80..BF + * U+D000..U+D7FF ED 80..9F 80..BF + * U+E000..U+FFFF EE..EF 80..BF 80..BF + * U+10000..U+3FFFF F0 90..BF 80..BF 80..BF + * U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF + * U+100000..U+10FFFF F4 80..8F 80..BF 80..BF + * + * In particular: + * + * (a) 0x00-0x7F are the only valid standalone bytes + * (b) 0xC2-0xF4 initiate a multi-byte sequence + * (c) 0x80-0xBF only valid as byte >= 2 of a multi-byte sequence + * (d) 0xC0, 0xC1, 0xF5-0xFF are never valid + */ + +#define ICONV_OPEN_FAILED 1 +#define ICONV_CLOSE_FAILED 2 + +int main(int argc, char** argv) { + const char* tocode = "UTF-8"; + const char* fromcode = "UTF-8"; + + iconv_t cd = iconv_open(tocode, fromcode); + if (cd == (iconv_t)(-1)) { + /* The errno values are standard, but we have no way of knowing + * if the implementation follows the standard! */ + fprintf(stderr, + "ERROR: iconv_open(\"%s\", \"%s\") returned ", + tocode, + fromcode); + switch (errno) { + case EMFILE: + fprintf(stderr, "EMFILE"); + break; + case ENFILE: + fprintf(stderr, "ENFILE"); + break; + case ENOMEM: + fprintf(stderr, "ENOMEM"); + break; + case EINVAL: + fprintf(stderr, "EINVAL"); + break; + default: + fprintf(stderr, "UNKNOWN"); + } + fprintf(stderr, "\n"); + return ICONV_OPEN_FAILED; + } + + /* actual conversion takes place here */ + + if (iconv_close(cd) == -1) { + /* The underlying type of iconv_t is unspecified, so we can't + * easily print the argument here. */ + fprintf(stderr, "ERROR: iconv_close() returned "); + switch (errno) { + case EBADF: + fprintf(stderr, "EBADF"); + break; + default: + fprintf(stderr, "UNKNOWN"); + } + fprintf(stderr, "\n"); + return ICONV_CLOSE_FAILED; + } + + return 0; +} -- 2.53.0