Remove iconv
This commit is contained in:
parent
11230c120d
commit
3e7037f621
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -17,3 +17,6 @@
|
|||||||
[submodule "dependencies/stb_image/include"]
|
[submodule "dependencies/stb_image/include"]
|
||||||
path = dependencies/stb_image/include
|
path = dependencies/stb_image/include
|
||||||
url = https://github.com/nothings/stb.git
|
url = https://github.com/nothings/stb.git
|
||||||
|
[submodule "dependencies/utf8cpp/src"]
|
||||||
|
path = dependencies/utf8cpp/src
|
||||||
|
url = https://github.com/nemtrif/utfcpp.git
|
||||||
|
@ -50,6 +50,7 @@ if("${toolchain_dir}/bin/arm-none-linux-gnueabihf-gcc" IS_NEWER_THAN "${sysroot_
|
|||||||
|
|
||||||
# Delete Unneeded Files
|
# Delete Unneeded Files
|
||||||
file(REMOVE_RECURSE "${sysroot_dir}/usr/lib/audit")
|
file(REMOVE_RECURSE "${sysroot_dir}/usr/lib/audit")
|
||||||
|
file(REMOVE_RECURSE "${sysroot_dir}/usr/lib/gconv")
|
||||||
|
|
||||||
# Strip Files
|
# Strip Files
|
||||||
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE "${sysroot_dir}/*")
|
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE "${sysroot_dir}/*")
|
||||||
@ -61,13 +62,6 @@ if("${toolchain_dir}/bin/arm-none-linux-gnueabihf-gcc" IS_NEWER_THAN "${sysroot_
|
|||||||
file(REMOVE "${file}")
|
file(REMOVE "${file}")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# Setup gconv
|
|
||||||
file(
|
|
||||||
COPY "${toolchain_dir}/arm-none-linux-gnueabihf/libc/usr/lib/gconv/gconv-modules"
|
|
||||||
DESTINATION "${sysroot_dir}/usr/lib/gconv"
|
|
||||||
USE_SOURCE_PERMISSIONS
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Install Sysroot (Skipping Empty Directories)
|
# Install Sysroot (Skipping Empty Directories)
|
||||||
|
2
dependencies/CMakeLists.txt
vendored
2
dependencies/CMakeLists.txt
vendored
@ -28,3 +28,5 @@ endif()
|
|||||||
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE AND MCPI_USE_GLES1_COMPATIBILITY_LAYER)
|
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE AND MCPI_USE_GLES1_COMPATIBILITY_LAYER)
|
||||||
add_subdirectory(gles-compatibility-layer)
|
add_subdirectory(gles-compatibility-layer)
|
||||||
endif()
|
endif()
|
||||||
|
# UTF8-CPP
|
||||||
|
add_subdirectory(utf8cpp)
|
||||||
|
2
dependencies/stb_image/CMakeLists.txt
vendored
2
dependencies/stb_image/CMakeLists.txt
vendored
@ -21,6 +21,8 @@ install(TARGETS stb_image DESTINATION "${MCPI_LIB_DIR}")
|
|||||||
install(
|
install(
|
||||||
DIRECTORY "include/"
|
DIRECTORY "include/"
|
||||||
DESTINATION "${MCPI_SDK_INCLUDE_DIR}/stb_image"
|
DESTINATION "${MCPI_SDK_INCLUDE_DIR}/stb_image"
|
||||||
|
FILES_MATCHING
|
||||||
|
PATTERN "*.h"
|
||||||
)
|
)
|
||||||
install(TARGETS stb_image EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
install(TARGETS stb_image EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||||
|
|
||||||
|
12
dependencies/utf8cpp/CMakeLists.txt
vendored
Normal file
12
dependencies/utf8cpp/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
project(utf8cpp)
|
||||||
|
|
||||||
|
# Silence Warnings
|
||||||
|
add_compile_options(-w)
|
||||||
|
|
||||||
|
## stb_image
|
||||||
|
|
||||||
|
# Build
|
||||||
|
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# License
|
||||||
|
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/utf8cpp")
|
1
dependencies/utf8cpp/src
vendored
Submodule
1
dependencies/utf8cpp/src
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit f6780f77f6824aa0fbe69f9b97ef7d8aba26ed92
|
@ -29,7 +29,6 @@ This component configures the various environmental variables required for MCPI-
|
|||||||
The environmental variables configured by this component includes:
|
The environmental variables configured by this component includes:
|
||||||
* ``LD_PRELOAD``
|
* ``LD_PRELOAD``
|
||||||
* ``LD_LIBRARY_PATH``
|
* ``LD_LIBRARY_PATH``
|
||||||
* ``GCONV_PATH``
|
|
||||||
* ``MCPI_FEATURE_FLAGS``
|
* ``MCPI_FEATURE_FLAGS``
|
||||||
* ``MCPI_RENDER_DISTANCE``
|
* ``MCPI_RENDER_DISTANCE``
|
||||||
* ``MCPI_USERNAME``
|
* ``MCPI_USERNAME``
|
||||||
|
@ -370,23 +370,6 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
set_and_print_env("MCPI_ARM_LD_LIBRARY_PATH", mcpi_ld_path);
|
set_and_print_env("MCPI_ARM_LD_LIBRARY_PATH", mcpi_ld_path);
|
||||||
free(mcpi_ld_path);
|
free(mcpi_ld_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup iconv
|
|
||||||
{
|
|
||||||
// Native Components
|
|
||||||
char *host_gconv_path = getenv("GCONV_PATH");
|
|
||||||
set_and_print_env("MCPI_NATIVE_GCONV_PATH", host_gconv_path);
|
|
||||||
|
|
||||||
// ARM Components
|
|
||||||
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
|
||||||
char *gconv_path = NULL;
|
|
||||||
safe_asprintf(&gconv_path, "%s/sysroot/usr/lib/gconv", binary_directory);
|
|
||||||
set_and_print_env("MCPI_ARM_GCONV_PATH", gconv_path);
|
|
||||||
free(gconv_path);
|
|
||||||
#else
|
|
||||||
set_and_print_env("MCPI_ARM_GCONV_PATH", host_gconv_path);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure Preloaded Objects
|
// Configure Preloaded Objects
|
||||||
|
@ -5,7 +5,7 @@ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn")
|
|||||||
configure_file(include/libreborn/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn/config.h" ESCAPE_QUOTES @ONLY)
|
configure_file(include/libreborn/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn/config.h" ESCAPE_QUOTES @ONLY)
|
||||||
|
|
||||||
# Util
|
# Util
|
||||||
add_library(reborn-util SHARED src/util/elf.c src/util/exec.c src/util/string.c src/util/util.c src/util/log.c)
|
add_library(reborn-util SHARED src/util/elf.c src/util/exec.c src/util/string.c src/util/util.c src/util/log.c src/util/cp437.cpp)
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
reborn-util
|
reborn-util
|
||||||
PUBLIC
|
PUBLIC
|
||||||
@ -13,6 +13,7 @@ target_include_directories(
|
|||||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
|
||||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/libreborn>"
|
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/libreborn>"
|
||||||
)
|
)
|
||||||
|
target_link_libraries(reborn-util PRIVATE utf8cpp)
|
||||||
# Install
|
# Install
|
||||||
install(TARGETS reborn-util DESTINATION "${MCPI_LIB_DIR}")
|
install(TARGETS reborn-util DESTINATION "${MCPI_LIB_DIR}")
|
||||||
# SDK
|
# SDK
|
||||||
|
@ -22,7 +22,6 @@ void set_and_print_env(const char *name, const char *value);
|
|||||||
// Safe execvpe()
|
// Safe execvpe()
|
||||||
#define for_each_special_environmental_variable(handle) \
|
#define for_each_special_environmental_variable(handle) \
|
||||||
handle("LD_LIBRARY_PATH"); \
|
handle("LD_LIBRARY_PATH"); \
|
||||||
handle("GCONV_PATH"); \
|
|
||||||
handle("LD_PRELOAD");
|
handle("LD_PRELOAD");
|
||||||
void setup_exec_environment(int is_arm_component);
|
void setup_exec_environment(int is_arm_component);
|
||||||
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);
|
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iconv.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -36,7 +35,6 @@ extern "C" {
|
|||||||
void sanitize_string(char **str, int max_length, unsigned int allow_newlines);
|
void sanitize_string(char **str, int max_length, unsigned int allow_newlines);
|
||||||
|
|
||||||
// CP437
|
// CP437
|
||||||
void safe_iconv(iconv_t cd, char *input, size_t input_size, char *output, size_t output_size);
|
|
||||||
char *to_cp437(const char *input);
|
char *to_cp437(const char *input);
|
||||||
char *from_cp437(const char *input);
|
char *from_cp437(const char *input);
|
||||||
|
|
||||||
|
91
libreborn/src/util/cp437.cpp
Normal file
91
libreborn/src/util/cp437.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
#include <libreborn/string.h>
|
||||||
|
|
||||||
|
// Conversion Functions
|
||||||
|
static std::u32string to_utf32(const std::string &s) {
|
||||||
|
return utf8::utf8to32(s);
|
||||||
|
}
|
||||||
|
static std::string to_utf8(const std::u32string &s) {
|
||||||
|
return utf8::utf32to8(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minecraft-Flavored CP437
|
||||||
|
#define CP437_CHARACTERS 256
|
||||||
|
static const std::string cp437_characters_map[CP437_CHARACTERS] = {
|
||||||
|
"\0", "☺", "☻", "♥", "♦", "♣", "♠", "•", "◘", "○", "\n", "♂", "♀", "\r", "♫", "☼",
|
||||||
|
"►", "◄", "↕", "‼", "¶", "§", "▬", "↨", "↑", "↓", "→", "←", "∟", "↔", "▲", "▼",
|
||||||
|
" ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/",
|
||||||
|
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
|
||||||
|
"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
|
||||||
|
"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_",
|
||||||
|
"`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
|
||||||
|
"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "⌂",
|
||||||
|
"Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å",
|
||||||
|
"É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ",
|
||||||
|
"á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»",
|
||||||
|
"░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐",
|
||||||
|
"└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "╧",
|
||||||
|
"╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀",
|
||||||
|
"α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩",
|
||||||
|
"≡", "±", "≥", "≤", "⌠", "⌡", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■", "©"
|
||||||
|
};
|
||||||
|
static uint32_t *get_cp437_characters_codepoint_map() {
|
||||||
|
static uint32_t map[CP437_CHARACTERS];
|
||||||
|
static int is_setup = 0;
|
||||||
|
if (!is_setup) {
|
||||||
|
// Build Map
|
||||||
|
for (int i = 0; i < CP437_CHARACTERS; i++) {
|
||||||
|
// Convert to UTF-32, Then Extract Codepoint
|
||||||
|
std::u32string str = to_utf32(cp437_characters_map[i]);
|
||||||
|
// Extract
|
||||||
|
map[i] = str[0];
|
||||||
|
}
|
||||||
|
is_setup = 1;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
char *to_cp437(const char *input) {
|
||||||
|
// Convert To UTF-32 For Easier Parsing
|
||||||
|
std::u32string utf32_str = to_utf32(input);
|
||||||
|
|
||||||
|
// Allocate String
|
||||||
|
std::string cp437_str;
|
||||||
|
|
||||||
|
// Handle Characters
|
||||||
|
for (size_t i = 0; i < utf32_str.length(); i++) {
|
||||||
|
uint32_t codepoint = utf32_str[i];
|
||||||
|
bool valid = false;
|
||||||
|
for (int j = 0; j < CP437_CHARACTERS; j++) {
|
||||||
|
uint32_t test_codepoint = get_cp437_characters_codepoint_map()[j];
|
||||||
|
if (codepoint == test_codepoint) {
|
||||||
|
valid = true;
|
||||||
|
cp437_str += j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!valid) {
|
||||||
|
cp437_str += '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return
|
||||||
|
return strdup(cp437_str.c_str());
|
||||||
|
}
|
||||||
|
char *from_cp437(const char *raw_input) {
|
||||||
|
// Convert To UTF-32 For Easier Parsing
|
||||||
|
std::string input = raw_input;
|
||||||
|
std::u32string utf32_str;
|
||||||
|
|
||||||
|
// Handle Characters
|
||||||
|
for (size_t i = 0; i < input.length(); i++) {
|
||||||
|
unsigned char c = (unsigned char) input[i];
|
||||||
|
utf32_str += get_cp437_characters_codepoint_map()[(uint32_t) c];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert To UTF-8
|
||||||
|
return strdup(to_utf8(utf32_str).c_str());
|
||||||
|
}
|
@ -1,4 +1,3 @@
|
|||||||
#include <iconv.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <libreborn/string.h>
|
#include <libreborn/string.h>
|
||||||
@ -23,125 +22,6 @@ void sanitize_string(char **str, int max_length, unsigned int allow_newlines) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minecraft-Flavored CP437
|
|
||||||
void safe_iconv(iconv_t cd, char *input, size_t input_size, char *output, size_t output_size) {
|
|
||||||
iconv(cd, &input, &input_size, &output, &output_size);
|
|
||||||
}
|
|
||||||
#define CP437_CHARACTERS 256
|
|
||||||
static const char *cp437_characters_map[CP437_CHARACTERS] = {
|
|
||||||
"\0", "☺", "☻", "♥", "♦", "♣", "♠", "•", "◘", "○", "\n", "♂", "♀", "\r", "♫", "☼",
|
|
||||||
"►", "◄", "↕", "‼", "¶", "§", "▬", "↨", "↑", "↓", "→", "←", "∟", "↔", "▲", "▼",
|
|
||||||
" ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/",
|
|
||||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
|
|
||||||
"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
|
|
||||||
"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_",
|
|
||||||
"`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
|
|
||||||
"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "⌂",
|
|
||||||
"Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å",
|
|
||||||
"É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ",
|
|
||||||
"á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»",
|
|
||||||
"░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐",
|
|
||||||
"└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "╧",
|
|
||||||
"╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀",
|
|
||||||
"α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩",
|
|
||||||
"≡", "±", "≥", "≤", "⌠", "⌡", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■", "©"
|
|
||||||
};
|
|
||||||
static uint32_t *get_cp437_characters_codepoint_map() {
|
|
||||||
static uint32_t map[CP437_CHARACTERS];
|
|
||||||
static int is_setup = 0;
|
|
||||||
if (!is_setup) {
|
|
||||||
// Build Map
|
|
||||||
iconv_t cd = iconv_open("UTF-32LE", "UTF-8");
|
|
||||||
if (cd != (iconv_t) -1) {
|
|
||||||
size_t str_size = 4;
|
|
||||||
uint32_t *str = (uint32_t *) malloc(str_size);
|
|
||||||
ALLOC_CHECK(str);
|
|
||||||
for (int i = 0; i < CP437_CHARACTERS; i++) {
|
|
||||||
// Convert to UTF-32, Then Extract Codepoint
|
|
||||||
safe_iconv(cd, (char *) cp437_characters_map[i], strlen(cp437_characters_map[i]), (char *) str, str_size);
|
|
||||||
// Extract
|
|
||||||
map[i] = str[0];
|
|
||||||
}
|
|
||||||
// Free
|
|
||||||
free(str);
|
|
||||||
iconv_close(cd);
|
|
||||||
} else {
|
|
||||||
IMPOSSIBLE();
|
|
||||||
}
|
|
||||||
is_setup = 1;
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
char *to_cp437(const char *input) {
|
|
||||||
// Convert To UTF-32 For Easier Parsing
|
|
||||||
size_t in_size = strlen(input);
|
|
||||||
size_t utf32_str_size = in_size * 4;
|
|
||||||
size_t real_utf32_str_size = utf32_str_size + 4 /* NULL-terminator */;
|
|
||||||
uint32_t *utf32_str = (uint32_t *) malloc(real_utf32_str_size);
|
|
||||||
ALLOC_CHECK(utf32_str);
|
|
||||||
memset(utf32_str, 0, real_utf32_str_size);
|
|
||||||
iconv_t cd = iconv_open("UTF-32LE", "UTF-8");
|
|
||||||
if (cd != (iconv_t) -1) {
|
|
||||||
safe_iconv(cd, (char *) input, in_size, (char *) utf32_str, utf32_str_size);
|
|
||||||
iconv_close(cd);
|
|
||||||
} else {
|
|
||||||
IMPOSSIBLE();
|
|
||||||
}
|
|
||||||
// Allocate String
|
|
||||||
size_t cp437_str_size;
|
|
||||||
for (cp437_str_size = 0; utf32_str[cp437_str_size] != 0; cp437_str_size++);
|
|
||||||
size_t real_cp437_str_size = cp437_str_size + 1 /* NULL-terminator */;
|
|
||||||
char *cp437_str = (char *) malloc(real_cp437_str_size);
|
|
||||||
ALLOC_CHECK(cp437_str);
|
|
||||||
memset(cp437_str, 0, real_cp437_str_size);
|
|
||||||
// Handle Characters
|
|
||||||
for (size_t i = 0; utf32_str[i] != 0; i++) {
|
|
||||||
uint32_t codepoint = utf32_str[i];
|
|
||||||
for (int j = 0; j < CP437_CHARACTERS; j++) {
|
|
||||||
uint32_t test_codepoint = get_cp437_characters_codepoint_map()[j];
|
|
||||||
if (codepoint == test_codepoint) {
|
|
||||||
cp437_str[i] = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cp437_str[i] == '\0') {
|
|
||||||
cp437_str[i] = '?';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Free
|
|
||||||
free(utf32_str);
|
|
||||||
// Return
|
|
||||||
return cp437_str;
|
|
||||||
}
|
|
||||||
char *from_cp437(const char *input) {
|
|
||||||
// Convert To UTF-32 For Easier Parsing
|
|
||||||
size_t in_size = strlen(input);
|
|
||||||
size_t utf32_str_size = in_size * 4;
|
|
||||||
size_t real_utf32_str_size = utf32_str_size + 4 /* NULL-terminator */;
|
|
||||||
uint32_t *utf32_str = (uint32_t *) malloc(real_utf32_str_size);
|
|
||||||
ALLOC_CHECK(utf32_str);
|
|
||||||
memset(utf32_str, 0, real_utf32_str_size);
|
|
||||||
// Handle Characters
|
|
||||||
for (size_t i = 0; input[i] != '\0'; i++) {
|
|
||||||
utf32_str[i] = get_cp437_characters_codepoint_map()[(uint32_t) input[i]];
|
|
||||||
}
|
|
||||||
// Convert To UTF-8
|
|
||||||
size_t out_size = utf32_str_size;
|
|
||||||
size_t real_out_size = utf32_str_size + 1 /* NULL-terminator */;
|
|
||||||
char *output = (char *) malloc(real_out_size);
|
|
||||||
ALLOC_CHECK(output);
|
|
||||||
memset(output, 0, real_out_size);
|
|
||||||
iconv_t cd = iconv_open("UTF-8", "UTF-32LE");
|
|
||||||
if (cd != (iconv_t) -1) {
|
|
||||||
safe_iconv(cd, (char *) utf32_str, utf32_str_size, output, out_size);
|
|
||||||
iconv_close(cd);
|
|
||||||
} else {
|
|
||||||
IMPOSSIBLE();
|
|
||||||
}
|
|
||||||
// Return
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starts With
|
// Starts With
|
||||||
int starts_with(const char *str, const char *prefix) {
|
int starts_with(const char *str, const char *prefix) {
|
||||||
return strncmp(prefix, str, strlen(prefix)) == 0;
|
return strncmp(prefix, str, strlen(prefix)) == 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user