summaryrefslogtreecommitdiff
path: root/Build/source/texk/gregorio/gregorio-src/src/unicode.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
committerKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
commitad547a6b5986815fda458221149728d9d9ab1d87 (patch)
tree16296910eb3eca724371474ea9aea3994dc69614 /Build/source/texk/gregorio/gregorio-src/src/unicode.c
parent947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff)
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/gregorio/gregorio-src/src/unicode.c')
-rw-r--r--Build/source/texk/gregorio/gregorio-src/src/unicode.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/Build/source/texk/gregorio/gregorio-src/src/unicode.c b/Build/source/texk/gregorio/gregorio-src/src/unicode.c
new file mode 100644
index 00000000000..fa9e2a4ac87
--- /dev/null
+++ b/Build/source/texk/gregorio/gregorio-src/src/unicode.c
@@ -0,0 +1,174 @@
+/*
+ * Gregorio is a program that translates gabc files to GregorioTeX
+ * This file contains functions providing UTF-8 support.
+ *
+ * Copyright (C) 2008-2019 The Gregorio Project (see CONTRIBUTORS.md)
+ *
+ * This file is part of Gregorio.
+ *
+ * Gregorio is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gregorio 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Gregorio. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h> /* for strlen */
+#include <stdlib.h>
+#include "struct.h"
+#include "unicode.h"
+#include "messages.h"
+#include "support.h"
+
+/*
+ *
+ * This file contains some functions to handle UTF-8 correctly. We chose to
+ * embed them instead of relying on locale or glib, for simplification: with
+ * these functions we don't rely on anything locale-dependant (such as
+ * wchar_t). The reason is that Windows XP (...) is not UTF-8 and thus would
+ * need the glib in oder to run, which make dependencies much bigger.
+ *
+ */
+
+/* an utf8 version of mbstowcs */
+
+/* expects a buffer of size n + 1 */
+static bool gregorio_mbstowcs(grewchar *dest, const char *src, size_t n)
+{
+ bool success = true;
+ unsigned char bytes_to_come;
+ grewchar result = 0;
+ unsigned char c;
+ size_t res = 0; /* number of bytes we've done so far */
+ gregorio_not_null(src, gregorio_mbstowcs, return false);
+ gregorio_not_null(dest, gregorio_mbstowcs, return false);
+ while (success && *src && res < n) {
+ c = (unsigned char) (*src);
+ if (c < 128) { /* 0100xxxx */
+ /* one-byte symbol */
+ bytes_to_come = 0;
+ result = c;
+ } else if (c >= 240) { /* 1111xxxx */
+ /* start of a four-byte symbol */
+ /* printf("%d\n", c); */
+ bytes_to_come = 3;
+ result = (result << 3) | (c & 7);
+ } else if (c >= 224) { /* 1110xxxx */
+ /* start of a three-byte symbol */
+ /* printf("%d\n", c); */
+ bytes_to_come = 2;
+ result = (result << 4) | (c & 15);
+ } else if (c >= 192) { /* 1100xxxx */
+ /* start of a two-byte symbol */
+ /* printf("%d\n", c); */
+ bytes_to_come = 1;
+ result = (result << 5) | (c & 31);
+ } else {
+ /* printf("%s %d %d\n", src, res, c); */
+ gregorio_message(_("malformed UTF-8 sequence1"),
+ "gregorio_mbstowcs", VERBOSITY_ERROR, 0);
+ success = false;
+ break;
+ }
+ while (bytes_to_come > 0) {
+ bytes_to_come--;
+ src++;
+ c = (unsigned char) (*src);
+ if (c < 192 && c >= 128) /* 1000xxxx */
+ {
+ result = (result << 6) | (c & 63);
+ } else {
+ gregorio_message(_("malformed UTF-8 sequence2"),
+ "gregorio_mbstowcs", VERBOSITY_ERROR, 0);
+ success = false;
+ break;
+ }
+ }
+ dest[res] = result;
+
+ res++;
+ result = 0;
+ src++;
+ }
+ dest[res] = 0;
+ return success;
+}
+
+/* the value returned by this function must be freed! */
+grewchar *gregorio_build_grewchar_string_from_buf(const char *const buf)
+{
+ size_t len;
+ grewchar *gwstring;
+ /* this doesn't currently happen, but it's safer to keep this check */
+ if (buf == NULL) {
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ len = strlen(buf); /* to get the length of the syllable in ASCII */
+ gwstring = (grewchar *) gregorio_malloc((len + 1) * sizeof(grewchar));
+ gregorio_mbstowcs(gwstring, buf, len); /* converting into grewchar */
+ /* no need to check the return code; if it failed, the error state would
+ * already be in place */
+ return gwstring;
+}
+
+/* the function to build a gregorio_character list from a buffer. */
+
+gregorio_character *gregorio_build_char_list_from_buf(const char *const buf)
+{
+ int i = 0;
+ grewchar *gwstring;
+ gregorio_character *current_character = NULL;
+ /* this doesn't currently happen, but it's safer to keep this check */
+ if (buf == NULL) {
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ gwstring = gregorio_build_grewchar_string_from_buf(buf);
+ /* we add the corresponding characters in the list of gregorio_characters */
+ while (gwstring[i]) {
+ gregorio_add_character(&current_character, gwstring[i]);
+ i++;
+ }
+ free(gwstring);
+ gregorio_go_to_first_character_c(&current_character);
+ return current_character;
+}
+
+void gregorio_print_unichar(FILE *f, const grewchar to_print)
+{
+ if (to_print <= 0x7F) {
+ fprintf(f, "%c", (unsigned char) to_print);
+ return;
+ }
+ if (to_print >= 0x80 && to_print <= 0x7FF) {
+ fprintf(f, "%c%c", 0xC0 | (to_print >> 6), 0x80 | (to_print & 0x3F));
+ return;
+ }
+ if ((to_print >= 0x800 && to_print <= 0xD7FF) ||
+ (to_print >= 0xE000 && to_print <= 0xFFFF)) {
+ fprintf(f, "%c%c%c", 0xE0 | (to_print >> 12),
+ 0x80 | ((to_print >> 6) & 0x3F), 0x80 | (to_print & 0x3F));
+ return;
+ }
+ if (to_print >= 0x10000 && to_print <= 0x10FFFF) {
+ fprintf(f, "%c%c%c%c", 0xF0 | (to_print >> 18),
+ 0x80 | ((to_print >> 12) & 0x3F),
+ 0x80 | ((to_print >> 6) & 0x3F), 0x80 | (to_print & 0x3F));
+ }
+}
+
+void gregorio_print_unistring(FILE *f, const grewchar *first_char)
+{
+ while (*first_char != 0) {
+ gregorio_print_unichar(f, *first_char);
+ first_char++;
+ }
+}