#include <math.h>
#include <stdio.h>
#include <windows.h>
#include "mavka/prystriy.h"
void out_utf8_data(п8* дані, природне розмір) {
if (розмір == 0) {
return;
}
// Convert UTF-8 to UTF-16 for Windows
int широких_символів =
MultiByteToWideChar(CP_UTF8, 0, (char*)дані, розмір, NULL, 0);
if (широких_символів == 0) {
return;
}
WCHAR* широкий_буфер =
(WCHAR*)пристрій_мавки_виділити(широких_символів * sizeof(WCHAR));
if (!широкий_буфер) {
return;
}
MultiByteToWideChar(CP_UTF8, 0, (char*)дані, розмір, широкий_буфер,
широких_символів);
// Write to console using Windows API
HANDLE консоль = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD записано;
WriteConsoleW(консоль, широкий_буфер, широких_символів, &записано, NULL);
пристрій_мавки_звільнити(широкий_буфер);
}
void out_utf8_string(char* дані) {
if (!дані) {
return;
}
// Calculate string length
природне довжина = 0;
while (дані[довжина] != '\0') {
довжина++;
}
out_utf8_data((п8*)дані, довжина);
}
extern логічне пристрій_мавки_отримати_версію_як_ю8(п8** вихід_даних,
природне* вихід_розміру) {
char* версія_ю8 = MAVKA_VERSION;
природне довжина_версії_ю8 = 0;
while (версія_ю8[довжина_версії_ю8] != '\0') {
довжина_версії_ю8++;
}
*вихід_розміру = довжина_версії_ю8;
*вихід_даних = (п8*)strdup((char*)версія_ю8);
return TRUE;
}
static void пристрій_мавки_вивести_колір(природне значення) {
HANDLE консоль = GetStdHandle(STD_OUTPUT_HANDLE);
// Enable virtual terminal processing for ANSI color support
DWORD режим;
if (GetConsoleMode(консоль, &режим)) {
SetConsoleMode(консоль, режим | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
}
WORD атрибути;
switch (значення) {
case КолірВиводуСтандартний:
атрибути = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
break;
case КолірВиводуЧервоний:
атрибути = FOREGROUND_RED | FOREGROUND_INTENSITY;
break;
case КолірВиводуЗелений:
атрибути = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
break;
case КолірВиводуСиній:
атрибути = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
break;
case КолірВиводуЖовтий:
атрибути = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
break;
default:
атрибути = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
break;
}
SetConsoleTextAttribute(консоль, атрибути);
}
extern void пристрій_мавки_вивести_сирі_дані(п8* дані, природне розмір) {
out_utf8_data(дані, розмір);
}
extern void пристрій_мавки_вивести_шлях(природне колір,
п8* дані,
природне розмір) {
пристрій_мавки_вивести_колір(колір);
out_utf8_data(дані, розмір);
пристрій_мавки_вивести_колір(КолірВиводуСтандартний);
}
extern void пристрій_мавки_вивести_ю8(природне колір,
п8* дані,
природне розмір) {
пристрій_мавки_вивести_колір(колір);
out_utf8_data(дані, розмір);
пристрій_мавки_вивести_колір(КолірВиводуСтандартний);
}
extern адреса пристрій_мавки_виділити(природне розмір) {
return (адреса)HeapAlloc(GetProcessHeap(), 0, розмір);
}
extern адреса пристрій_мавки_перевиділити(адреса значення,
природне новий_розмір) {
if (значення == NULL) {
return (адреса)HeapAlloc(GetProcessHeap(), 0, новий_розмір);
}
return (адреса)HeapReAlloc(GetProcessHeap(), 0, значення, новий_розмір);
}
extern void пристрій_мавки_звільнити(адреса значення) {
if (значення != NULL) {
HeapFree(GetProcessHeap(), 0, значення);
}
}
extern void пристрій_мавки_вийти(ц32 код_виходу) {
ExitProcess((UINT)код_виходу);
}
extern логічне пристрій_мавки_прочитати_файл(п8* дані_шляху,
природне розмір_шляху,
п8** вихід_даних,
природне* вихід_розміру) {
// Convert UTF-8 path to wide char
int широких_символів =
MultiByteToWideChar(CP_UTF8, 0, (char*)дані_шляху, розмір_шляху, NULL, 0);
if (широких_символів == 0) {
return FALSE;
}
WCHAR* широкий_шлях = (WCHAR*)HeapAlloc(
GetProcessHeap(), 0, (широких_символів + 1) * sizeof(WCHAR));
if (!широкий_шлях) {
return FALSE;
}
MultiByteToWideChar(CP_UTF8, 0, (char*)дані_шляху, розмір_шляху, широкий_шлях,
широких_символів);
широкий_шлях[широких_символів] = L'\0';
// Open file using Windows API
HANDLE файл = CreateFileW(широкий_шлях, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
пристрій_мавки_звільнити(широкий_шлях);
if (файл == INVALID_HANDLE_VALUE) {
return FALSE;
}
// Get file size
LARGE_INTEGER розмір_файлу;
if (!GetFileSizeEx(файл, &розмір_файлу)) {
CloseHandle(файл);
return FALSE;
}
*вихід_розміру = (природне)розмір_файлу.QuadPart;
// Allocate buffer
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних) {
CloseHandle(файл);
return FALSE;
}
// Read file
DWORD прочитано;
if (!ReadFile(файл, *вихід_даних, *вихід_розміру, &прочитано, NULL)) {
пристрій_мавки_звільнити(*вихід_даних);
CloseHandle(файл);
return FALSE;
}
CloseHandle(файл);
return TRUE;
}
логічне пристрій_мавки_перетворити_п64_в_ю8(п64 значення,
п8** вихід_даних,
природне* вихід_розміру) {
char буфер[32];
int довжина = wsprintfA(буфер, "%I64u", значення);
if (довжина <= 0) {
return FALSE;
}
*вихід_розміру = (природне)довжина;
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних) {
return FALSE;
}
for (природне і = 0; і < *вихід_розміру; і++) {
(*вихід_даних)[і] = (п8)буфер[і];
}
return TRUE;
}
логічне пристрій_мавки_перетворити_ц64_в_ю8(ц64 значення,
п8** вихід_даних,
природне* вихід_розміру) {
char буфер[32];
int довжина = wsprintfA(буфер, "%I64d", значення);
if (довжина <= 0) {
return FALSE;
}
*вихід_розміру = (природне)довжина;
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних) {
return FALSE;
}
for (природне і = 0; і < *вихід_розміру; і++) {
(*вихід_даних)[і] = (п8)буфер[і];
}
return TRUE;
}
логічне пристрій_мавки_перетворити_р64_в_ю8(р64 значення,
п8** вихід_даних,
природне* вихід_розміру,
ціле* вихід_розміру_експоненти) {
char буфер[64];
int довжина;
// Check for NaN
if (значення != значення) { // NaN != NaN
char nan_str[] = "невизначеність";
*вихід_розміру = sizeof(nan_str) - 1;
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних)
return FALSE;
for (природне і = 0; і < *вихід_розміру; і++) {
(*вихід_даних)[і] = (п8)nan_str[і];
}
*вихід_розміру_експоненти = 0;
return TRUE;
}
// Check for infinity
if (значення > 1e308 || значення < -1e308) {
char* inf_str = значення > 0 ? "нескінченність" : "-нескінченність";
*вихід_розміру = значення > 0 ? sizeof("нескінченність") - 1
: sizeof("-нескінченність") - 1;
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних)
return FALSE;
for (природне і = 0; і < *вихід_розміру; і++) {
(*вихід_даних)[і] = (п8)inf_str[і];
}
*вихід_розміру_експоненти = 0;
return TRUE;
}
довжина = sprintf(буфер, "%.17g", значення);
if (довжина < 0 || довжина >= (int)sizeof(буфер)) {
return FALSE;
}
// Знаходимо найкоротше представлення, яке round-trips
// Пробуємо від 15 до 17 цифр точності
for (int precision = 15; precision <= 17; precision++) {
довжина = sprintf(буфер, "%.*g", precision, значення);
if (довжина < 0 || довжина >= (int)sizeof(буфер)) {
continue;
}
// Перевіряємо чи round-trip працює
р64 parsed = strtod(буфер, NULL);
if (parsed == значення) {
break;
}
}
if (довжина < 0 || довжина >= (int)sizeof(буфер)) {
return FALSE;
}
// Find 'e' for exponential notation
char* e_pos = NULL;
for (int і = 0; і < довжина; і++) {
if (буфер[і] == 'e') {
e_pos = &буфер[і];
break;
}
}
if (e_pos != NULL) {
// Parse exponent
*вихід_розміру_експоненти = 0;
ціле знак_експоненти = 1;
char* p = e_pos + 1;
if (*p == '+') {
p++;
} else if (*p == '-') {
знак_експоненти = -1;
p++;
}
while (*p >= '0' && *p <= '9') {
*вихід_розміру_експоненти = *вихід_розміру_експоненти * 10 + (*p - '0');
p++;
}
*вихід_розміру_експоненти *= знак_експоненти;
природне довжина_мантиси = (природне)(e_pos - буфер);
*вихід_розміру = довжина_мантиси;
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних)
return FALSE;
for (природне і = 0; і < довжина_мантиси; і++) {
(*вихід_даних)[і] = (п8)буфер[і];
}
} else {
*вихід_розміру_експоненти = 0;
*вихід_розміру = (природне)довжина;
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних)
return FALSE;
for (природне і = 0; і < *вихід_розміру; і++) {
(*вихід_даних)[і] = (п8)буфер[і];
}
}
return TRUE;
}
логічне пристрій_мавки_отримати_р64_з_ю8(п8* дані,
природне розмір,
р64* вихід) {
int широких_символів =
MultiByteToWideChar(CP_UTF8, 0, (char*)дані, розмір, NULL, 0);
if (широких_символів == 0) {
return FALSE;
}
WCHAR* широкий_рядок =
(WCHAR*)пристрій_мавки_виділити((широких_символів + 1) * sizeof(WCHAR));
if (!широкий_рядок) {
return FALSE;
}
MultiByteToWideChar(CP_UTF8, 0, (char*)дані, розмір, широкий_рядок,
широких_символів);
широкий_рядок[широких_символів] = L'\0';
for (int i = 0; i < широких_символів; i++) {
if (широкий_рядок[i] == L'е') {
широкий_рядок[i] = L'e';
} else if (широкий_рядок[i] == L'Е') {
широкий_рядок[i] = L'E';
}
}
WCHAR* endptr;
*вихід = wcstod(широкий_рядок, &endptr);
if (широкий_рядок == endptr) {
пристрій_мавки_звільнити(широкий_рядок);
return FALSE;
} else if (errno == ERANGE) {
пристрій_мавки_звільнити(широкий_рядок);
return FALSE;
} else if (*endptr != L'\0') {
пристрій_мавки_звільнити(широкий_рядок);
return FALSE;
}
пристрій_мавки_звільнити(широкий_рядок);
return TRUE;
}
extern р64 пристрій_мавки_піднести_до_степеня_р64(р64 значення, р64 степінь) {
return pow(значення, степінь);
}
extern логічне пристрій_мавки_перевірити_чи_шлях_існує_і_є_файлом(
п8* дані_шляху,
природне розмір_шляху) {
// Convert UTF-8 path to wide char
int широких_символів =
MultiByteToWideChar(CP_UTF8, 0, (char*)дані_шляху, розмір_шляху, NULL, 0);
if (широких_символів == 0) {
return FALSE;
}
WCHAR* широкий_шлях = (WCHAR*)HeapAlloc(
GetProcessHeap(), 0, (широких_символів + 1) * sizeof(WCHAR));
if (!широкий_шлях) {
return FALSE;
}
MultiByteToWideChar(CP_UTF8, 0, (char*)дані_шляху, розмір_шляху, широкий_шлях,
широких_символів);
широкий_шлях[широких_символів] = L'\0';
// Get file attributes using Windows API
DWORD атрибути = GetFileAttributesW(широкий_шлях);
пристрій_мавки_звільнити(широкий_шлях);
if (атрибути == INVALID_FILE_ATTRIBUTES) {
return FALSE;
}
// Check if it's a regular file (not a directory)
return (атрибути & FILE_ATTRIBUTE_DIRECTORY) == 0;
}
extern логічне пристрій_мавки_отримати_абсолютний_шлях(
п8* дані_шляху,
природне розмір_шляху,
п8** вихід_даних,
природне* вихід_розміру) {
// Convert UTF-8 path to wide char
int широких_символів =
MultiByteToWideChar(CP_UTF8, 0, (char*)дані_шляху, розмір_шляху, NULL, 0);
if (широких_символів == 0) {
return FALSE;
}
WCHAR* широкий_шлях = (WCHAR*)HeapAlloc(
GetProcessHeap(), 0, (широких_символів + 1) * sizeof(WCHAR));
if (!широкий_шлях) {
return FALSE;
}
MultiByteToWideChar(CP_UTF8, 0, (char*)дані_шляху, розмір_шляху, широкий_шлях,
широких_символів);
широкий_шлях[широких_символів] = L'\0';
// Get full path using Windows API
DWORD потрібно = GetFullPathNameW(широкий_шлях, 0, NULL, NULL);
if (потрібно == 0) {
пристрій_мавки_звільнити(широкий_шлях);
return FALSE;
}
WCHAR* абсолютний_широкий =
(WCHAR*)пристрій_мавки_виділити(потрібно * sizeof(WCHAR));
if (!абсолютний_широкий) {
пристрій_мавки_звільнити(широкий_шлях);
return FALSE;
}
if (GetFullPathNameW(широкий_шлях, потрібно, абсолютний_широкий, NULL) == 0) {
пристрій_мавки_звільнити(абсолютний_широкий);
пристрій_мавки_звільнити(широкий_шлях);
return FALSE;
}
пристрій_мавки_звільнити(широкий_шлях);
// Convert back to UTF-8
int байтів_ю8 = WideCharToMultiByte(CP_UTF8, 0, абсолютний_широкий, -1, NULL,
0, NULL, NULL);
if (байтів_ю8 == 0) {
пристрій_мавки_звільнити(абсолютний_широкий);
return FALSE;
}
*вихід_розміру = байтів_ю8 - 1; // Exclude null terminator
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних) {
пристрій_мавки_звільнити(абсолютний_широкий);
return FALSE;
}
WideCharToMultiByte(CP_UTF8, 0, абсолютний_широкий, -1, (char*)*вихід_даних,
байтів_ю8, NULL, NULL);
пристрій_мавки_звільнити(абсолютний_широкий);
return TRUE;
}
extern логічне пристрій_мавки_отримати_теку_шляху(п8* дані_шляху,
природне розмір_шляху,
п8** вихід_даних,
природне* вихід_розміру,
природне рівень) {
// Convert UTF-8 path to wide char
int широких_символів =
MultiByteToWideChar(CP_UTF8, 0, (char*)дані_шляху, розмір_шляху, NULL, 0);
if (широких_символів == 0) {
return FALSE;
}
WCHAR* широкий_шлях = (WCHAR*)HeapAlloc(
GetProcessHeap(), 0, (широких_символів + 1) * sizeof(WCHAR));
if (!широкий_шлях) {
return FALSE;
}
MultiByteToWideChar(CP_UTF8, 0, (char*)дані_шляху, розмір_шляху, широкий_шлях,
широких_символів);
широкий_шлях[широких_символів] = L'\0';
// Find parent directory 'рівень' times
for (природне і = 0; і < рівень; і++) {
// Find last backslash or forward slash
WCHAR* остання_коса = NULL;
for (int j = широких_символів - 1; j >= 0; j--) {
if (широкий_шлях[j] == L'\\') {
остання_коса = &широкий_шлях[j];
широких_символів = j;
break;
}
}
if (остання_коса) {
*остання_коса = L'\0';
} else {
// No more parent directories
break;
}
}
// Convert back to UTF-8
int байтів_ю8 =
WideCharToMultiByte(CP_UTF8, 0, широкий_шлях, -1, NULL, 0, NULL, NULL);
if (байтів_ю8 == 0) {
пристрій_мавки_звільнити(широкий_шлях);
return FALSE;
}
*вихід_розміру = байтів_ю8 - 1; // Exclude null terminator
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних) {
пристрій_мавки_звільнити(широкий_шлях);
return FALSE;
}
WideCharToMultiByte(CP_UTF8, 0, широкий_шлях, -1, (char*)*вихід_даних,
байтів_ю8 - 1, NULL, NULL);
пристрій_мавки_звільнити(широкий_шлях);
return TRUE;
}
extern логічне пристрій_мавки_отримати_теку_до_паків(п8* дані_шляху,
природне розмір_шляху,
п8** вихід_даних,
природне* вихід_розміру) {
const char* паки_суфікс = "\\паки";
природне довжина_суфікса = 0;
while (паки_суфікс[довжина_суфікса] != '\0') {
довжина_суфікса++;
}
*вихід_розміру = розмір_шляху + довжина_суфікса;
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних) {
return FALSE;
}
for (природне і = 0; і < розмір_шляху; і++) {
(*вихід_даних)[і] = дані_шляху[і];
}
for (природне і = 0; і < довжина_суфікса; і++) {
(*вихід_даних)[розмір_шляху + і] = (п8)паки_суфікс[і];
}
return TRUE;
}
extern логічне пристрій_мавки_отримати_назву_модуля_з_шляху_ю8(
п8* дані_шляху,
природне розмір_шляху,
п8** вихід_даних,
природне* вихід_розміру) {
// Find the last slash or backslash to get basename
природне позиція_останньої_коси = 0;
логічне знайдено_косу = FALSE;
for (природне і = 0; і < розмір_шляху; і++) {
if (дані_шляху[і] == '\\') {
позиція_останньої_коси = і + 1;
знайдено_косу = TRUE;
}
}
// Extract basename
природне початок_назви = знайдено_косу ? позиція_останньої_коси : 0;
природне довжина_назви = розмір_шляху - початок_назви;
// Check and remove ".м" suffix
const char* суфікс = ".м";
природне довжина_суфікса = 0;
while (суфікс[довжина_суфікса] != '\0') {
довжина_суфікса++;
}
if (довжина_назви >= довжина_суфікса) {
логічне має_суфікс = TRUE;
for (природне і = 0; і < довжина_суфікса; і++) {
if (дані_шляху[початок_назви + довжина_назви - довжина_суфікса + і] !=
(п8)суфікс[і]) {
має_суфікс = FALSE;
break;
}
}
if (має_суфікс) {
довжина_назви -= довжина_суфікса;
}
}
// Create a copy of the name for conversion
п8* назва_ю8 = (п8*)пристрій_мавки_виділити(довжина_назви);
if (!назва_ю8) {
return FALSE;
}
for (природне і = 0; і < довжина_назви; і++) {
назва_ю8[і] = дані_шляху[початок_назви + і];
}
*вихід_розміру = довжина_назви;
*вихід_даних = назва_ю8;
return TRUE;
}
extern логічне пристрій_мавки_збити_шлях_до_модуля(
природне кількість_елементів,
ЕлементШляхуПристроюМавки* елементи,
п8** вихід_даних,
природне* вихід_розміру) {
const char* суфікс = ".м";
природне довжина_суфікса = 0;
while (суфікс[довжина_суфікса] != '\0') {
довжина_суфікса++;
}
природне загальний_розмір = кількість_елементів - 1 + довжина_суфікса;
for (природне і = 0; і < кількість_елементів; і++) {
загальний_розмір += елементи[і].розмір;
}
*вихід_розміру = загальний_розмір;
*вихід_даних = (п8*)пристрій_мавки_виділити(загальний_розмір);
if (!*вихід_даних) {
return FALSE;
}
природне позиція = 0;
for (природне і = 0; і < кількість_елементів; і++) {
for (природне j = 0; j < елементи[і].розмір; j++) {
(*вихід_даних)[позиція++] = елементи[і].дані[j];
}
if (і < кількість_елементів - 1) {
(*вихід_даних)[позиція++] = '\\';
}
}
for (природне і = 0; і < довжина_суфікса; і++) {
(*вихід_даних)[позиція++] = (п8)суфікс[і];
}
return TRUE;
}
extern логічне пристрій_мавки_перевірити_чи_шлях_починається_на(
п8* дані_шляху,
природне розмір_шляху,
п8* дані_початку,
природне розмір_початку) {
if (розмір_початку > розмір_шляху) {
return FALSE;
}
for (природне і = 0; і < розмір_початку; і++) {
if (дані_шляху[і] != дані_початку[і]) {
return FALSE;
}
}
return TRUE;
}
extern логічне пристрій_мавки_отримати_шлях_до_паку_з_шляху_теки_модулів(
п8* дані_шляху,
природне розмір_шляху,
п8* дані_шляху_до_паків,
природне розмір_шляху_до_паків,
п8** вихід_даних,
природне* вихід_розміру) {
// Check if the module path starts with the packages path
if (розмір_шляху <= розмір_шляху_до_паків) {
return FALSE;
}
// Verify that the module path starts with the packages path
for (природне і = 0; і < розмір_шляху_до_паків; і++) {
if (дані_шляху[і] != дані_шляху_до_паків[і]) {
return FALSE;
}
}
// Find the next '\\' after the packages path to get the package directory
природне позиція_наступного_слешу = 0;
логічне знайдено = FALSE;
// Skip the packages path and any immediate '\\'
природне початок = розмір_шляху_до_паків;
if (початок < розмір_шляху && дані_шляху[початок] == '\\') {
початок++;
}
// Find the next '\\' which marks the end of the package name
for (природне і = початок; і < розмір_шляху; і++) {
if (дані_шляху[і] == '\\') {
позиція_наступного_слешу = і; // Don't include the trailing slash
знайдено = TRUE;
break;
}
}
if (!знайдено) {
позиція_наступного_слешу = розмір_шляху;
}
// Return the path up to but not including the trailing slash
*вихід_розміру = позиція_наступного_слешу;
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних) {
return FALSE;
}
for (природне і = 0; і < позиція_наступного_слешу; і++) {
(*вихід_даних)[і] = дані_шляху[і];
}
return TRUE;
}
static char* do_readline(char* prefix, size_t prefix_size, size_t* out_len) {
пристрій_мавки_вивести_ю8(КолірВиводуСтандартний, (п8*)prefix,
(природне)prefix_size);
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE) {
return NULL;
}
// Read wide characters (UTF-16) for proper Unicode support
size_t wide_cap = 128;
size_t wide_len = 0;
WCHAR* wide_buf = (WCHAR*)пристрій_мавки_виділити(wide_cap * sizeof(WCHAR));
if (!wide_buf)
return NULL;
WCHAR wc;
DWORD charsRead;
while (ReadConsoleW(hStdin, &wc, 1, &charsRead, NULL) && charsRead == 1) {
if (wc == L'\n')
break; // stop, but DON'T store '\n'
if (wc == L'\r')
continue; // skip '\r' in Windows line endings
if (wide_len + 1 >= wide_cap) {
wide_cap *= 2;
WCHAR* tmp = (WCHAR*)пристрій_мавки_перевиділити(
wide_buf, wide_cap * sizeof(WCHAR));
if (!tmp) {
пристрій_мавки_звільнити(wide_buf);
return NULL;
}
wide_buf = tmp;
}
wide_buf[wide_len++] = wc;
}
// If nothing read, return NULL
if (wide_len == 0) {
пристрій_мавки_звільнити(wide_buf);
return NULL;
}
// Convert UTF-16 to UTF-8
int utf8_size =
WideCharToMultiByte(CP_UTF8, 0, wide_buf, wide_len, NULL, 0, NULL, NULL);
if (utf8_size == 0) {
пристрій_мавки_звільнити(wide_buf);
return NULL;
}
char* buf = (char*)пристрій_мавки_виділити(utf8_size + 1);
if (!buf) {
пристрій_мавки_звільнити(wide_buf);
return NULL;
}
WideCharToMultiByte(CP_UTF8, 0, wide_buf, wide_len, buf, utf8_size, NULL,
NULL);
buf[utf8_size] = '\0';
пристрій_мавки_звільнити(wide_buf);
if (out_len)
*out_len = utf8_size;
return buf;
}
extern логічне пристрій_мавки_читати_ю8(п8* дані_перед,
природне розмір_перед,
п8** вихід_даних,
природне* вихід_розміру,
природне* вихід_кінець_файлу,
природне дозволити_історію) {
пристрій_мавки_вивести_ю8(КолірВиводуСтандартний, дані_перед, розмір_перед);
size_t len;
char* data = do_readline((char*)дані_перед, (size_t)розмір_перед, &len);
if (!data) {
*вихід_кінець_файлу = TRUE;
return TRUE;
}
*вихід_розміру = (природне)len;
*вихід_даних = (п8*)data;
*вихід_кінець_файлу = FALSE;
return TRUE;
}
extern логічне пристрій_мавки_читати_ю8_асинхронно(
п8* дані_перед,
природне розмір_перед,
void (*обробник)(п8* дані,
природне розмір,
природне кінець_файлу,
адреса аргумент),
адреса аргумент,
природне дозволити_історію) {
size_t len;
char* data = do_readline((char*)дані_перед, (size_t)розмір_перед, &len);
if (!data) {
обробник((п8*)data, (природне)len, TRUE, аргумент);
return TRUE;
}
обробник((п8*)data, (природне)len, FALSE, аргумент);
return TRUE;
}
extern логічне пристрій_мавки_отримати_поточний_шлях_процесу(
п8** вихід_даних,
природне* вихід_розміру) {
// Get required buffer size for current directory (in wide chars)
DWORD розмір = GetCurrentDirectoryW(0, NULL);
if (розмір == 0) {
return FALSE;
}
// Allocate buffer for wide char path
WCHAR* широкий_шлях = (WCHAR*)пристрій_мавки_виділити(розмір * sizeof(WCHAR));
if (!широкий_шлях) {
return FALSE;
}
// Get current directory as wide char
if (GetCurrentDirectoryW(розмір, широкий_шлях) == 0) {
пристрій_мавки_звільнити(широкий_шлях);
return FALSE;
}
// Convert UTF-16 to UTF-8
int байтів_ю8 =
WideCharToMultiByte(CP_UTF8, 0, широкий_шлях, -1, NULL, 0, NULL, NULL);
if (байтів_ю8 == 0) {
пристрій_мавки_звільнити(широкий_шлях);
return FALSE;
}
// Allocate buffer for UTF-8 (excluding null terminator)
*вихід_розміру = байтів_ю8 - 1;
*вихід_даних = (п8*)пристрій_мавки_виділити(*вихід_розміру);
if (!*вихід_даних) {
пристрій_мавки_звільнити(широкий_шлях);
return FALSE;
}
// Convert to UTF-8
WideCharToMultiByte(CP_UTF8, 0, широкий_шлях, -1, (char*)*вихід_даних,
байтів_ю8, NULL, NULL);
пристрій_мавки_звільнити(широкий_шлях);
return TRUE;
}