loadsave.c: Add functions to open file with alternate extension.
Used by CPC format which are in several files : PPH format uses PPH, ODD, EVE CM5 uses CM5 + GFX
This commit is contained in:
parent
fda4708756
commit
be824627ce
@ -2321,6 +2321,7 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context
|
|||||||
T_IO_Context preview_context;
|
T_IO_Context preview_context;
|
||||||
|
|
||||||
Init_context_preview(&preview_context, Selector_filename, Selector->Directory);
|
Init_context_preview(&preview_context, Selector_filename, Selector->Directory);
|
||||||
|
preview_context.File_name_unicode = Selector_filename_unicode;
|
||||||
Hide_cursor();
|
Hide_cursor();
|
||||||
if (context->Type == CONTEXT_PALETTE)
|
if (context->Type == CONTEXT_PALETTE)
|
||||||
preview_context.Type = CONTEXT_PREVIEW_PALETTE;
|
preview_context.Type = CONTEXT_PREVIEW_PALETTE;
|
||||||
|
|||||||
128
src/loadsave.c
128
src/loadsave.c
@ -1787,6 +1787,38 @@ FILE * Open_file_write(T_IO_Context *context)
|
|||||||
return fopen(filename, "wb");
|
return fopen(filename, "wb");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ext)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
char filename[MAX_PATH_CHARACTERS]; // filename with full path
|
||||||
|
#if defined(WIN32)
|
||||||
|
WCHAR filename_unicode[MAX_PATH_CHARACTERS];
|
||||||
|
WCHAR * pw;
|
||||||
|
|
||||||
|
if (context->File_name_unicode != NULL)
|
||||||
|
{
|
||||||
|
Unicode_char_strlcpy((word *)filename_unicode, context->File_directory, MAX_PATH_CHARACTERS);
|
||||||
|
Unicode_char_strlcat((word *)filename_unicode, PATH_SEPARATOR, MAX_PATH_CHARACTERS);
|
||||||
|
Unicode_strlcat((word *)filename_unicode, context->File_name_unicode, MAX_PATH_CHARACTERS);
|
||||||
|
pw = wcschr(filename_unicode, (WCHAR)'.');
|
||||||
|
if (pw != NULL)
|
||||||
|
*pw = 0;
|
||||||
|
Unicode_char_strlcat((word *)filename_unicode, ".", MAX_PATH_CHARACTERS);
|
||||||
|
Unicode_char_strlcat((word *)filename_unicode, ext, MAX_PATH_CHARACTERS);
|
||||||
|
|
||||||
|
return _wfopen(filename_unicode, L"wb");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||||
|
p = strrchr(filename, '.');
|
||||||
|
if (p != NULL)
|
||||||
|
*p = '\0';
|
||||||
|
strcat(filename, ".");
|
||||||
|
strcat(filename, ext);
|
||||||
|
|
||||||
|
return fopen(filename, "wb");
|
||||||
|
}
|
||||||
|
|
||||||
/// For use by Load_XXX() and Test_XXX() functions
|
/// For use by Load_XXX() and Test_XXX() functions
|
||||||
FILE * Open_file_read(T_IO_Context *context)
|
FILE * Open_file_read(T_IO_Context *context)
|
||||||
{
|
{
|
||||||
@ -1797,6 +1829,102 @@ FILE * Open_file_read(T_IO_Context *context)
|
|||||||
return fopen(filename, "rb");
|
return fopen(filename, "rb");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct T_Find_alternate_ext_data
|
||||||
|
{
|
||||||
|
const char * ext;
|
||||||
|
char basename[MAX_PATH_CHARACTERS];
|
||||||
|
word basename_unicode[MAX_PATH_CHARACTERS];
|
||||||
|
char foundname[MAX_PATH_CHARACTERS];
|
||||||
|
word foundname_unicode[MAX_PATH_CHARACTERS];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Look_for_alternate_ext(void * pdata, const char * filename, const word * filename_unicode, byte is_file, byte is_directory, byte is_hidden)
|
||||||
|
{
|
||||||
|
size_t base_len;
|
||||||
|
struct T_Find_alternate_ext_data * params = (struct T_Find_alternate_ext_data *)pdata;
|
||||||
|
(void)is_hidden;
|
||||||
|
(void)is_directory;
|
||||||
|
|
||||||
|
if (!is_file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (filename_unicode != NULL && params->basename_unicode[0] != 0)
|
||||||
|
{
|
||||||
|
base_len = Unicode_strlen(params->basename_unicode);
|
||||||
|
if (filename_unicode[base_len] != '.')
|
||||||
|
return; // No match.
|
||||||
|
#if defined(WIN32)
|
||||||
|
{
|
||||||
|
WCHAR temp_string[MAX_PATH_CHARACTERS];
|
||||||
|
memcpy(temp_string, filename_unicode, base_len * sizeof(word));
|
||||||
|
temp_string[base_len] = 0;
|
||||||
|
if (_wcsicmp((const WCHAR *)params->basename_unicode, temp_string) != 0)
|
||||||
|
return; // No match.
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (memcmp(params->basename_unicode, filename_unicode, base_len * sizeof(word)) != 0)
|
||||||
|
return; // No match.
|
||||||
|
#endif
|
||||||
|
if (Unicode_char_strcasecmp(filename_unicode + base_len + 1, params->ext) != 0)
|
||||||
|
return; // No match.
|
||||||
|
// it is a match !
|
||||||
|
Unicode_strlcpy(params->foundname_unicode, filename_unicode, MAX_PATH_CHARACTERS);
|
||||||
|
strncpy(params->foundname, filename, MAX_PATH_CHARACTERS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base_len = strlen(params->basename);
|
||||||
|
if (filename[base_len] != '.')
|
||||||
|
return; // No match.
|
||||||
|
#if defined(WIN32)
|
||||||
|
if (_memicmp(params->basename, filename, base_len) != 0) // Not case sensitive
|
||||||
|
return; // No match.
|
||||||
|
#else
|
||||||
|
if (memcmp(params->basename, filename, base_len) != 0)
|
||||||
|
return; // No match.
|
||||||
|
#endif
|
||||||
|
if (strcasecmp(filename + base_len + 1, params->ext) != 0)
|
||||||
|
return; // No match.
|
||||||
|
params->foundname_unicode[0] = 0;
|
||||||
|
strncpy(params->foundname, filename, MAX_PATH_CHARACTERS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE * Open_file_read_with_alternate_ext(T_IO_Context *context, const char * ext)
|
||||||
|
{
|
||||||
|
char * p;
|
||||||
|
struct T_Find_alternate_ext_data params;
|
||||||
|
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
|
params.ext = ext;
|
||||||
|
strncpy(params.basename, context->File_name, MAX_PATH_CHARACTERS);
|
||||||
|
p = strrchr(params.basename, '.');
|
||||||
|
if (p != NULL)
|
||||||
|
*p = '\0';
|
||||||
|
if (context->File_name_unicode != NULL)
|
||||||
|
{
|
||||||
|
size_t i = Unicode_strlen(context->File_name_unicode);
|
||||||
|
memcpy(params.basename_unicode, context->File_name_unicode, (i + 1) * sizeof(word));
|
||||||
|
while (i-- > 0)
|
||||||
|
if (params.basename_unicode[i] == (word)'.')
|
||||||
|
{
|
||||||
|
params.basename_unicode[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
For_each_directory_entry(context->File_directory, ¶ms, Look_for_alternate_ext);
|
||||||
|
if (params.foundname[0] != '\0')
|
||||||
|
{
|
||||||
|
char filename[MAX_PATH_CHARACTERS]; // filename with full path
|
||||||
|
|
||||||
|
Get_full_filename(filename, params.foundname, context->File_directory);
|
||||||
|
|
||||||
|
return fopen(filename, "rb");
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/// For use by Save_XXX() functions
|
/// For use by Save_XXX() functions
|
||||||
void Remove_file(T_IO_Context *context)
|
void Remove_file(T_IO_Context *context)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -267,6 +267,13 @@ FILE * Open_file_write(T_IO_Context *context);
|
|||||||
/// For use by Load_XXX() and Test_XXX() functions
|
/// For use by Load_XXX() and Test_XXX() functions
|
||||||
FILE * Open_file_read(T_IO_Context *context);
|
FILE * Open_file_read(T_IO_Context *context);
|
||||||
|
|
||||||
|
/// For use by Load_XXX() and Test_XXX() functions
|
||||||
|
FILE * Open_file_read_with_alternate_ext(T_IO_Context *context, const char * ext);
|
||||||
|
|
||||||
/// For use by Save_XXX() functions
|
/// For use by Save_XXX() functions
|
||||||
void Remove_file(T_IO_Context *context);
|
void Remove_file(T_IO_Context *context);
|
||||||
|
|
||||||
|
/// For use by Save_XXX() functions
|
||||||
|
FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ext);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -3217,15 +3217,12 @@ void Load_CM5(T_IO_Context* context)
|
|||||||
// Set palette to the CPC hardware colors
|
// Set palette to the CPC hardware colors
|
||||||
// Load the palette data to the 4 colorlayers
|
// Load the palette data to the 4 colorlayers
|
||||||
FILE *file;
|
FILE *file;
|
||||||
char filename[MAX_PATH_CHARACTERS];
|
|
||||||
byte value = 0;
|
byte value = 0;
|
||||||
int mod=0;
|
int mod=0;
|
||||||
short line = 0;
|
short line = 0;
|
||||||
int tx, ty;
|
int tx, ty;
|
||||||
byte buffer[48*6/4];
|
byte buffer[48*6/4];
|
||||||
|
|
||||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
|
||||||
|
|
||||||
if (!(file = Open_file_read(context)))
|
if (!(file = Open_file_read(context)))
|
||||||
{
|
{
|
||||||
File_error = 1;
|
File_error = 1;
|
||||||
@ -3330,22 +3327,11 @@ void Load_CM5(T_IO_Context* context)
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
// Load the pixeldata to the 5th layer
|
// Load the pixeldata to the 5th layer
|
||||||
|
file = Open_file_read_with_alternate_ext(context, "gfx");
|
||||||
|
if (file == NULL)
|
||||||
{
|
{
|
||||||
char* ext = filename + strlen(filename) - 3;
|
File_error = 1;
|
||||||
int idx = 8;
|
return;
|
||||||
do {
|
|
||||||
if (-- idx < 0)
|
|
||||||
{
|
|
||||||
File_error = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ext[0] = (idx & 1) ? 'g':'G';
|
|
||||||
ext[1] = (idx & 2) ? 'f':'F';
|
|
||||||
ext[2] = (idx & 4) ? 'x':'X';
|
|
||||||
|
|
||||||
file = fopen(filename, "rb");
|
|
||||||
} while(file == NULL);
|
|
||||||
}
|
}
|
||||||
Set_loading_layer(context, 4);
|
Set_loading_layer(context, 4);
|
||||||
|
|
||||||
@ -3368,12 +3354,9 @@ void Load_CM5(T_IO_Context* context)
|
|||||||
|
|
||||||
void Save_CM5(T_IO_Context* context)
|
void Save_CM5(T_IO_Context* context)
|
||||||
{
|
{
|
||||||
char filename[MAX_PATH_CHARACTERS];
|
|
||||||
FILE* file;
|
FILE* file;
|
||||||
int tx, ty;
|
int tx, ty;
|
||||||
|
|
||||||
|
|
||||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
|
||||||
// TODO: Check picture has 5 layers
|
// TODO: Check picture has 5 layers
|
||||||
// TODO: Check the constraints on the layers
|
// TODO: Check the constraints on the layers
|
||||||
// Layer 1 : 1 color Only
|
// Layer 1 : 1 color Only
|
||||||
@ -3407,12 +3390,10 @@ void Save_CM5(T_IO_Context* context)
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
// Now the pixeldata
|
// Now the pixeldata
|
||||||
filename[strlen(filename) - 3] = 0;
|
if (!(file = Open_file_write_with_alternate_ext(context, "gfx")))
|
||||||
strcat(filename,"gfx");
|
|
||||||
if (!(file = fopen(filename, "wb")))
|
|
||||||
{
|
{
|
||||||
File_error = 2;
|
File_error = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setvbuf(file, NULL, _IOFBF, 64*1024);
|
setvbuf(file, NULL, _IOFBF, 64*1024);
|
||||||
|
|
||||||
@ -3460,91 +3441,92 @@ void Save_CM5(T_IO_Context* context)
|
|||||||
void Test_PPH(T_IO_Context * context)
|
void Test_PPH(T_IO_Context * context)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
char buffer[MAX_PATH_CHARACTERS];
|
byte buffer[6];
|
||||||
long file_size;
|
long file_size;
|
||||||
int w;
|
int w;
|
||||||
int expected;
|
int expected;
|
||||||
|
|
||||||
File_error = 1;
|
File_error = 1;
|
||||||
|
|
||||||
if ((file = Open_file_read(context)))
|
file = Open_file_read(context);
|
||||||
{
|
if (file == NULL)
|
||||||
// First check file size is large enough to hold the header
|
return;
|
||||||
file_size = File_length_file(file);
|
|
||||||
if (file_size < 11) {
|
|
||||||
File_error = 1;
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
// File is large enough for the header, now check if the data makes some sense
|
// First check file size is large enough to hold the header
|
||||||
fread(buffer, 1, 6, file);
|
file_size = File_length_file(file);
|
||||||
if (buffer[0] > 5) {
|
if (file_size < 11) {
|
||||||
// Unknown mode
|
File_error = 1;
|
||||||
File_error = 2;
|
goto abort;
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
w = buffer[1] | (buffer[2] << 8);
|
|
||||||
if (w < 2 || w > 384) {
|
|
||||||
// Invalid width
|
|
||||||
File_error = 3;
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
w = buffer[3] | (buffer[4] << 8);
|
|
||||||
if (w < 1 || w > 272) {
|
|
||||||
// Invalid height
|
|
||||||
File_error = 4;
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer[5] < 1 || buffer[5] > 28)
|
|
||||||
{
|
|
||||||
// Invalid palettes count
|
|
||||||
File_error = 5;
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
expected = 6; // Size of header
|
|
||||||
switch(buffer[0])
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
// Palette size should be 16 bytes, only 1 palette.
|
|
||||||
if (buffer[5] != 1) {
|
|
||||||
File_error = 7;
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
expected += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
case 5:
|
|
||||||
expected += buffer[5] * 5 - 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
// Palete size should be 2 bytes
|
|
||||||
if (buffer[5] != 1) {
|
|
||||||
File_error = 7;
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
expected += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_size != expected)
|
|
||||||
{
|
|
||||||
File_error = 6;
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
File_error = 0;
|
|
||||||
} else {
|
|
||||||
File_error = 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// File is large enough for the header, now check if the data makes some sense
|
||||||
|
if (!Read_bytes(file, buffer, 6))
|
||||||
|
goto abort;
|
||||||
|
if (buffer[0] > 5) {
|
||||||
|
// Unknown mode
|
||||||
|
File_error = 2;
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
w = buffer[1] | (buffer[2] << 8);
|
||||||
|
if (w < 2 || w > 384) {
|
||||||
|
// Invalid width
|
||||||
|
File_error = 3;
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
w = buffer[3] | (buffer[4] << 8);
|
||||||
|
if (w < 1 || w > 272) {
|
||||||
|
// Invalid height
|
||||||
|
File_error = 4;
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer[5] < 1 || buffer[5] > 28)
|
||||||
|
{
|
||||||
|
// Invalid palettes count
|
||||||
|
File_error = 5;
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
expected = 6; // Size of header
|
||||||
|
switch(buffer[0])
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
// Palette size should be 16 bytes, only 1 palette.
|
||||||
|
if (buffer[5] != 1) {
|
||||||
|
File_error = 7;
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
expected += 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case 5:
|
||||||
|
expected += buffer[5] * 5 - 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
// Palette size should be 2 bytes
|
||||||
|
if (buffer[5] != 1) {
|
||||||
|
File_error = 7;
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
expected += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_size != expected)
|
||||||
|
{
|
||||||
|
File_error = 6;
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
File_error = 0;
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
fclose(file);
|
if (file != NULL)
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
// TODO: check existence of .ODD/.EVE files with the same name
|
// TODO: check existence of .ODD/.EVE files with the same name
|
||||||
}
|
}
|
||||||
@ -3564,7 +3546,6 @@ void Load_PPH(T_IO_Context* context)
|
|||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
FILE *feven;
|
FILE *feven;
|
||||||
char filename[MAX_PATH_CHARACTERS];
|
|
||||||
|
|
||||||
// Read in the header
|
// Read in the header
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
@ -3574,7 +3555,6 @@ void Load_PPH(T_IO_Context* context)
|
|||||||
int i,j;
|
int i,j;
|
||||||
uint8_t a,b,c,d;
|
uint8_t a,b,c,d;
|
||||||
int file_size;
|
int file_size;
|
||||||
char* ext;
|
|
||||||
uint8_t pl[16];
|
uint8_t pl[16];
|
||||||
|
|
||||||
static const T_Components CPCPAL[27] =
|
static const T_Components CPCPAL[27] =
|
||||||
@ -3590,8 +3570,6 @@ void Load_PPH(T_IO_Context* context)
|
|||||||
{ 0xF3, 0xF3, 0x0D }, { 0xF3, 0xF3, 0x6D }, { 0xFF, 0xF3, 0xF9 }
|
{ 0xF3, 0xF3, 0x0D }, { 0xF3, 0xF3, 0x6D }, { 0xFF, 0xF3, 0xF9 }
|
||||||
};
|
};
|
||||||
|
|
||||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
|
||||||
|
|
||||||
if (!(file = Open_file_read(context)))
|
if (!(file = Open_file_read(context)))
|
||||||
{
|
{
|
||||||
File_error = 1;
|
File_error = 1;
|
||||||
@ -3713,18 +3691,19 @@ void Load_PPH(T_IO_Context* context)
|
|||||||
// Load the picture data
|
// Load the picture data
|
||||||
// There are two pages, each storing bytes in the CPC vram format but lines in
|
// There are two pages, each storing bytes in the CPC vram format but lines in
|
||||||
// linear order.
|
// linear order.
|
||||||
ext = filename + strlen(filename) - 3; // TODO : make a function to load file with another extension !
|
file = Open_file_read_with_alternate_ext(context, "odd");
|
||||||
ext[0] = 'O';
|
if (file == NULL)
|
||||||
ext[1] = 'D';
|
{
|
||||||
ext[2] = 'D';
|
File_error = 3;
|
||||||
|
return;
|
||||||
file = fopen(filename, "rb");
|
}
|
||||||
|
feven = Open_file_read_with_alternate_ext(context, "eve");
|
||||||
ext[0] = 'E';
|
if (feven == NULL)
|
||||||
ext[1] = 'V';
|
{
|
||||||
ext[2] = 'E';
|
File_error = 4;
|
||||||
|
fclose(file);
|
||||||
feven = fopen(filename, "rb");
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
d = 0;
|
d = 0;
|
||||||
|
|||||||
@ -87,6 +87,28 @@ int Unicode_char_strcmp(const word * s1, const char * s2)
|
|||||||
return (*s1 > *str2) ? 1 : -1;
|
return (*s1 > *str2) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compare an unicode string with a regular Latin1 string. Ignoring case
|
||||||
|
int Unicode_char_strcasecmp(const word * s1, const char * s2)
|
||||||
|
{
|
||||||
|
const byte * str2 = (const byte *)s2;
|
||||||
|
unsigned int c1, c2;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
c1 = *s1++;
|
||||||
|
c2 = *str2++;
|
||||||
|
// first convert to lower case
|
||||||
|
if ('a' <= c1 && c1 <= 'z')
|
||||||
|
c1 -= ('a'-'A');
|
||||||
|
if ('a' <= c2 && c2 <= 'z')
|
||||||
|
c2 -= ('a'-'A');
|
||||||
|
if (c1 != c2)
|
||||||
|
return (c1 > c2) ? 1 : -1;
|
||||||
|
if (c1 == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Copy a regular Latin1 string to an unicode string
|
/// Copy a regular Latin1 string to an unicode string
|
||||||
void Unicode_char_strlcpy(word * dst, const char * src, size_t len)
|
void Unicode_char_strlcpy(word * dst, const char * src, size_t len)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -39,6 +39,9 @@ void Unicode_strlcat(word * dst, const word * src, size_t len);
|
|||||||
/// Compare an unicode string with a regular Latin1 string
|
/// Compare an unicode string with a regular Latin1 string
|
||||||
int Unicode_char_strcmp(const word * s1, const char * s2);
|
int Unicode_char_strcmp(const word * s1, const char * s2);
|
||||||
|
|
||||||
|
/// Compare an unicode string with a regular Latin1 string. Ignoring case
|
||||||
|
int Unicode_char_strcasecmp(const word * s1, const char * s2);
|
||||||
|
|
||||||
/// Copy a regular Latin1 string to an unicode string
|
/// Copy a regular Latin1 string to an unicode string
|
||||||
void Unicode_char_strlcpy(word * dst, const char * src, size_t len);
|
void Unicode_char_strlcpy(word * dst, const char * src, size_t len);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user