diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
commit | ad547a6b5986815fda458221149728d9d9ab1d87 (patch) | |
tree | 16296910eb3eca724371474ea9aea3994dc69614 /Build/source/texk/gregorio/gregorio-src/src/unicode.c | |
parent | 947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (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.c | 174 |
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(¤t_character, gwstring[i]); + i++; + } + free(gwstring); + gregorio_go_to_first_character_c(¤t_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++; + } +} |