2011-10-15 14:56:47 +04:00
|
|
|
/*
|
|
|
|
Text conversion from one charset to another.
|
2002-08-27 09:27:11 +04:00
|
|
|
|
2024-01-01 09:46:17 +03:00
|
|
|
Copyright (C) 2001-2024
|
2014-02-12 10:33:10 +04:00
|
|
|
Free Software Foundation, Inc.
|
2002-08-27 09:27:11 +04:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
Written by:
|
|
|
|
Walery Studennikov <despair@sama.ru>
|
2002-08-27 09:27:11 +04:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
This file is part of the Midnight Commander.
|
|
|
|
|
|
|
|
The Midnight Commander 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.
|
|
|
|
|
|
|
|
The Midnight Commander is distributed in the hope that it will be useful,
|
2002-08-27 09:27:11 +04:00
|
|
|
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
|
2011-10-15 14:56:47 +04:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2002-08-27 09:27:11 +04:00
|
|
|
*/
|
|
|
|
|
2009-02-05 21:28:18 +03:00
|
|
|
/** \file charsets.c
|
|
|
|
* \brief Source: Text conversion from one charset to another
|
|
|
|
*/
|
|
|
|
|
2001-05-31 05:27:20 +04:00
|
|
|
#include <config.h>
|
2001-06-01 03:56:27 +04:00
|
|
|
|
2001-05-31 05:27:20 +04:00
|
|
|
#include <stdio.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
#include <stdlib.h>
|
2001-05-31 05:27:20 +04:00
|
|
|
#include <string.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
|
2010-01-20 18:11:52 +03:00
|
|
|
#include "lib/global.h"
|
2010-11-09 14:02:28 +03:00
|
|
|
#include "lib/strutil.h" /* utf-8 functions */
|
2010-01-21 15:17:26 +03:00
|
|
|
#include "lib/fileloc.h"
|
2016-12-11 21:31:22 +03:00
|
|
|
#include "lib/util.h" /* whitespace() */
|
|
|
|
|
2010-11-18 11:31:09 +03:00
|
|
|
#include "lib/charsets.h"
|
2010-01-21 15:17:26 +03:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/*** global variables ****************************************************************************/
|
|
|
|
|
2010-09-16 13:39:29 +04:00
|
|
|
GPtrArray *codepages = NULL;
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2002-10-31 02:14:26 +03:00
|
|
|
unsigned char conv_displ[256];
|
|
|
|
unsigned char conv_input[256];
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2009-04-22 20:20:42 +04:00
|
|
|
const char *cp_display = NULL;
|
|
|
|
const char *cp_source = NULL;
|
2009-04-17 18:05:19 +04:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/*** file scope macro definitions ****************************************************************/
|
|
|
|
|
2012-04-30 15:52:39 +04:00
|
|
|
#define UNKNCHAR '\001'
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
#define OTHER_8BIT "Other_8_bit"
|
|
|
|
|
|
|
|
/*** file scope type declarations ****************************************************************/
|
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/*** forward declarations (file scope functions) *************************************************/
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/*** file scope variables ************************************************************************/
|
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-11-09 14:02:28 +03:00
|
|
|
/*** file scope functions ************************************************************************/
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-09-16 13:39:29 +04:00
|
|
|
static codepage_desc *
|
|
|
|
new_codepage_desc (const char *id, const char *name)
|
|
|
|
{
|
|
|
|
codepage_desc *desc;
|
2009-04-17 18:05:19 +04:00
|
|
|
|
2010-09-16 13:39:29 +04:00
|
|
|
desc = g_new (codepage_desc, 1);
|
|
|
|
desc->id = g_strdup (id);
|
|
|
|
desc->name = g_strdup (name);
|
|
|
|
|
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-09-16 13:39:29 +04:00
|
|
|
static void
|
2023-02-12 13:19:37 +03:00
|
|
|
free_codepage_desc (gpointer data)
|
2010-09-16 13:39:29 +04:00
|
|
|
{
|
|
|
|
codepage_desc *desc = (codepage_desc *) data;
|
|
|
|
|
|
|
|
g_free (desc->id);
|
|
|
|
g_free (desc->name);
|
|
|
|
g_free (desc);
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-09-16 13:39:29 +04:00
|
|
|
/* returns display codepage */
|
2010-11-09 14:02:28 +03:00
|
|
|
|
2010-09-16 13:39:29 +04:00
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
load_codepages_list_from_file (GPtrArray **list, const char *fname)
|
2001-05-31 05:27:20 +04:00
|
|
|
{
|
|
|
|
FILE *f;
|
2009-07-07 10:54:31 +04:00
|
|
|
char buf[BUF_MEDIUM];
|
2002-10-31 02:14:26 +03:00
|
|
|
char *default_codepage = NULL;
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2010-03-30 22:59:41 +04:00
|
|
|
f = fopen (fname, "r");
|
2010-09-16 13:39:29 +04:00
|
|
|
if (f == NULL)
|
|
|
|
return;
|
|
|
|
|
2012-07-16 16:14:33 +04:00
|
|
|
while (fgets (buf, sizeof buf, f) != NULL)
|
2010-09-16 13:39:29 +04:00
|
|
|
{
|
|
|
|
/* split string into id and cpname */
|
|
|
|
char *p = buf;
|
2018-01-21 11:39:17 +03:00
|
|
|
size_t buflen;
|
2010-09-16 13:39:29 +04:00
|
|
|
|
|
|
|
if (*p == '\n' || *p == '\0' || *p == '#')
|
|
|
|
continue;
|
|
|
|
|
2018-01-21 11:39:17 +03:00
|
|
|
buflen = strlen (buf);
|
|
|
|
|
|
|
|
if (buflen != 0 && buf[buflen - 1] == '\n')
|
2010-09-16 13:39:29 +04:00
|
|
|
buf[buflen - 1] = '\0';
|
2016-12-11 21:31:22 +03:00
|
|
|
while (*p != '\0' && !whitespace (*p))
|
2010-09-16 13:39:29 +04:00
|
|
|
++p;
|
|
|
|
if (*p == '\0')
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
*p++ = '\0';
|
|
|
|
g_strstrip (p);
|
|
|
|
if (*p == '\0')
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (strcmp (buf, "default") == 0)
|
|
|
|
default_codepage = g_strdup (p);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const char *id = buf;
|
|
|
|
|
|
|
|
if (*list == NULL)
|
|
|
|
{
|
2024-03-31 19:14:07 +03:00
|
|
|
*list = g_ptr_array_new_full (16, free_codepage_desc);
|
2010-09-16 13:39:29 +04:00
|
|
|
g_ptr_array_add (*list, new_codepage_desc (id, p));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-07-16 16:14:33 +04:00
|
|
|
unsigned int i;
|
|
|
|
|
2010-09-16 13:39:29 +04:00
|
|
|
/* whether id is already present in list */
|
|
|
|
/* if yes, overwrite description */
|
|
|
|
for (i = 0; i < (*list)->len; i++)
|
|
|
|
{
|
|
|
|
codepage_desc *desc;
|
|
|
|
|
|
|
|
desc = (codepage_desc *) g_ptr_array_index (*list, i);
|
|
|
|
|
|
|
|
if (strcmp (id, desc->id) == 0)
|
|
|
|
{
|
|
|
|
/* found */
|
|
|
|
g_free (desc->name);
|
|
|
|
desc->name = g_strdup (p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* not found */
|
|
|
|
if (i == (*list)->len)
|
|
|
|
g_ptr_array_add (*list, new_codepage_desc (id, p));
|
|
|
|
}
|
|
|
|
}
|
2001-08-12 07:27:27 +04:00
|
|
|
}
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2010-09-16 13:39:29 +04:00
|
|
|
if (default_codepage != NULL)
|
|
|
|
{
|
2011-02-10 18:02:54 +03:00
|
|
|
mc_global.display_codepage = get_codepage_index (default_codepage);
|
2010-09-16 13:39:29 +04:00
|
|
|
g_free (default_codepage);
|
2001-05-31 05:27:20 +04:00
|
|
|
}
|
|
|
|
|
2002-10-31 02:14:26 +03:00
|
|
|
fail:
|
|
|
|
fclose (f);
|
2001-05-31 05:27:20 +04:00
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static char
|
|
|
|
translate_character (GIConv cd, char c)
|
|
|
|
{
|
|
|
|
gchar *tmp_buff = NULL;
|
|
|
|
gsize bytes_read, bytes_written = 0;
|
|
|
|
const char *ibuf = &c;
|
|
|
|
char ch = UNKNCHAR;
|
|
|
|
int ibuflen = 1;
|
|
|
|
|
|
|
|
tmp_buff = g_convert_with_iconv (ibuf, ibuflen, cd, &bytes_read, &bytes_written, NULL);
|
2018-01-21 11:39:17 +03:00
|
|
|
if (tmp_buff != NULL)
|
2010-11-09 14:02:28 +03:00
|
|
|
ch = tmp_buff[0];
|
|
|
|
g_free (tmp_buff);
|
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/*** public functions ****************************************************************************/
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2002-10-31 02:14:26 +03:00
|
|
|
void
|
2010-09-16 13:39:29 +04:00
|
|
|
load_codepages_list (void)
|
2001-10-29 16:40:00 +03:00
|
|
|
{
|
2010-09-16 13:39:29 +04:00
|
|
|
char *fname;
|
|
|
|
|
|
|
|
/* 1: try load /usr/share/mc/mc.charsets */
|
2011-02-10 18:02:54 +03:00
|
|
|
fname = g_build_filename (mc_global.share_data_dir, CHARSETS_LIST, (char *) NULL);
|
2010-09-16 13:39:29 +04:00
|
|
|
load_codepages_list_from_file (&codepages, fname);
|
|
|
|
g_free (fname);
|
|
|
|
|
|
|
|
/* 2: try load /etc/mc/mc.charsets */
|
2011-02-10 18:02:54 +03:00
|
|
|
fname = g_build_filename (mc_global.sysconfig_dir, CHARSETS_LIST, (char *) NULL);
|
2010-09-16 13:39:29 +04:00
|
|
|
load_codepages_list_from_file (&codepages, fname);
|
|
|
|
g_free (fname);
|
|
|
|
|
|
|
|
if (codepages == NULL)
|
|
|
|
{
|
Fix various typos in the source code (closes MidnightCommander/mc#177).
Found via `codespell -S
po,doc,./misc/syntax,./src/vfs/extfs/helpers/README.it -L
parm,rouge,sav,ect,vie,te,dum,clen,wee,dynamc,childs,ths,fo,nin,unx,nd,iif,iterm,ser,makrs,wil`
Co-authored-by: Yury V. Zaytsev <yury@shurup.com>
Signed-off-by: Kian-Meng Ang <kianmeng@cpan.org>
Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
2023-01-10 06:02:52 +03:00
|
|
|
/* files are not found, add default codepage */
|
2010-09-16 13:39:29 +04:00
|
|
|
fprintf (stderr, "%s\n", _("Warning: cannot load codepages list"));
|
|
|
|
|
2023-02-12 13:19:37 +03:00
|
|
|
codepages = g_ptr_array_new_with_free_func (free_codepage_desc);
|
2013-09-09 16:55:01 +04:00
|
|
|
g_ptr_array_add (codepages, new_codepage_desc (DEFAULT_CHARSET, _("7-bit ASCII")));
|
2001-10-29 16:40:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-09-16 13:39:29 +04:00
|
|
|
void
|
|
|
|
free_codepages_list (void)
|
|
|
|
{
|
|
|
|
g_ptr_array_free (codepages, TRUE);
|
2016-11-12 18:58:05 +03:00
|
|
|
/* NULL-ize pointer to make unit tests happy */
|
|
|
|
codepages = NULL;
|
2010-09-16 13:39:29 +04:00
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2004-08-30 02:38:06 +04:00
|
|
|
const char *
|
2009-04-20 11:30:32 +04:00
|
|
|
get_codepage_id (const int n)
|
2001-05-31 05:27:20 +04:00
|
|
|
{
|
2010-09-16 13:39:29 +04:00
|
|
|
return (n < 0) ? OTHER_8BIT : ((codepage_desc *) g_ptr_array_index (codepages, n))->id;
|
2001-05-31 05:27:20 +04:00
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2002-10-31 02:14:26 +03:00
|
|
|
int
|
|
|
|
get_codepage_index (const char *id)
|
2001-05-31 05:27:20 +04:00
|
|
|
{
|
2010-10-21 11:34:27 +04:00
|
|
|
size_t i;
|
2018-01-18 23:53:25 +03:00
|
|
|
|
2009-07-01 09:58:58 +04:00
|
|
|
if (codepages == NULL)
|
2010-11-09 14:02:28 +03:00
|
|
|
return -1;
|
2018-01-18 23:53:25 +03:00
|
|
|
if (strcmp (id, OTHER_8BIT) == 0)
|
|
|
|
return -1;
|
2010-09-16 13:39:29 +04:00
|
|
|
for (i = 0; i < codepages->len; i++)
|
2010-11-09 14:02:28 +03:00
|
|
|
if (strcmp (id, ((codepage_desc *) g_ptr_array_index (codepages, i))->id) == 0)
|
|
|
|
return i;
|
2001-05-31 05:27:20 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-09-27 12:02:32 +04:00
|
|
|
/** Check if specified encoding can be used in mc.
|
|
|
|
* @param encoding name of encoding
|
2012-11-05 17:57:50 +04:00
|
|
|
* @return TRUE if encoding is supported by mc, FALSE otherwise
|
2010-09-27 12:02:32 +04:00
|
|
|
*/
|
2010-11-09 14:02:28 +03:00
|
|
|
|
2010-09-13 13:32:27 +04:00
|
|
|
gboolean
|
|
|
|
is_supported_encoding (const char *encoding)
|
|
|
|
{
|
2024-10-03 14:29:28 +03:00
|
|
|
GIConv coder;
|
|
|
|
gboolean result;
|
2010-09-13 13:32:27 +04:00
|
|
|
|
2024-10-03 14:29:28 +03:00
|
|
|
if (encoding == NULL)
|
|
|
|
return FALSE;
|
2010-09-13 13:32:27 +04:00
|
|
|
|
2024-10-03 14:29:28 +03:00
|
|
|
coder = str_crt_conv_from (encoding);
|
|
|
|
result = coder != INVALID_CONV;
|
|
|
|
if (result)
|
|
|
|
str_close_conv (coder);
|
2010-09-13 13:32:27 +04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2001-06-08 00:04:03 +04:00
|
|
|
|
2010-03-31 14:02:45 +04:00
|
|
|
char *
|
2002-10-31 02:14:26 +03:00
|
|
|
init_translation_table (int cpsource, int cpdisplay)
|
2001-05-31 05:27:20 +04:00
|
|
|
{
|
|
|
|
int i;
|
2009-04-28 14:03:02 +04:00
|
|
|
GIConv cd;
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2024-09-06 10:55:26 +03:00
|
|
|
/* Fill input <-> display tables */
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
if (cpsource < 0 || cpdisplay < 0 || cpsource == cpdisplay)
|
|
|
|
{
|
|
|
|
for (i = 0; i <= 255; ++i)
|
|
|
|
{
|
|
|
|
conv_displ[i] = i;
|
|
|
|
conv_input[i] = i;
|
|
|
|
}
|
2018-01-18 23:53:25 +03:00
|
|
|
cp_source = cp_display;
|
2010-11-09 14:02:28 +03:00
|
|
|
return NULL;
|
2001-05-31 05:27:20 +04:00
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
for (i = 0; i <= 127; ++i)
|
|
|
|
{
|
|
|
|
conv_displ[i] = i;
|
|
|
|
conv_input[i] = i;
|
2001-05-31 05:27:20 +04:00
|
|
|
}
|
2010-09-16 13:39:29 +04:00
|
|
|
cp_source = ((codepage_desc *) g_ptr_array_index (codepages, cpsource))->id;
|
|
|
|
cp_display = ((codepage_desc *) g_ptr_array_index (codepages, cpdisplay))->id;
|
2001-05-31 05:27:20 +04:00
|
|
|
|
|
|
|
/* display <- inpit table */
|
|
|
|
|
2009-04-28 14:03:02 +04:00
|
|
|
cd = g_iconv_open (cp_display, cp_source);
|
2010-03-31 14:02:45 +04:00
|
|
|
if (cd == INVALID_CONV)
|
2010-11-09 14:02:28 +03:00
|
|
|
return g_strdup_printf (_("Cannot translate from %s to %s"), cp_source, cp_display);
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2002-10-31 02:14:26 +03:00
|
|
|
for (i = 128; i <= 255; ++i)
|
2010-11-09 14:02:28 +03:00
|
|
|
conv_displ[i] = translate_character (cd, i);
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2009-04-28 14:03:02 +04:00
|
|
|
g_iconv_close (cd);
|
2001-05-31 05:27:20 +04:00
|
|
|
|
|
|
|
/* inpit <- display table */
|
|
|
|
|
2009-04-28 14:03:02 +04:00
|
|
|
cd = g_iconv_open (cp_source, cp_display);
|
2010-03-31 14:02:45 +04:00
|
|
|
if (cd == INVALID_CONV)
|
2010-11-09 14:02:28 +03:00
|
|
|
return g_strdup_printf (_("Cannot translate from %s to %s"), cp_display, cp_source);
|
2001-05-31 05:27:20 +04:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
for (i = 128; i <= 255; ++i)
|
|
|
|
{
|
|
|
|
unsigned char ch;
|
|
|
|
ch = translate_character (cd, i);
|
|
|
|
conv_input[i] = (ch == UNKNCHAR) ? i : ch;
|
2001-05-31 05:27:20 +04:00
|
|
|
}
|
|
|
|
|
2009-04-28 14:03:02 +04:00
|
|
|
g_iconv_close (cd);
|
2001-05-31 05:27:20 +04:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2002-10-31 02:14:26 +03:00
|
|
|
void
|
|
|
|
convert_to_display (char *str)
|
2001-05-31 05:27:20 +04:00
|
|
|
{
|
2018-01-21 11:39:17 +03:00
|
|
|
if (str != NULL)
|
|
|
|
for (; *str != '\0'; str++)
|
|
|
|
*str = conv_displ[(unsigned char) *str];
|
2001-05-31 05:27:20 +04:00
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2009-04-21 15:19:42 +04:00
|
|
|
GString *
|
2016-03-29 10:39:41 +03:00
|
|
|
str_nconvert_to_display (const char *str, int len)
|
2009-04-17 18:05:19 +04:00
|
|
|
{
|
|
|
|
GString *buff;
|
|
|
|
GIConv conv;
|
|
|
|
|
2018-01-21 11:39:17 +03:00
|
|
|
if (str == NULL)
|
2023-05-21 13:05:18 +03:00
|
|
|
return NULL;
|
2009-04-17 18:05:19 +04:00
|
|
|
|
|
|
|
if (cp_display == cp_source)
|
2010-11-09 14:02:28 +03:00
|
|
|
return g_string_new (str);
|
2009-04-17 18:05:19 +04:00
|
|
|
|
2009-04-21 15:19:42 +04:00
|
|
|
conv = str_crt_conv_from (cp_source);
|
2024-09-13 12:29:37 +03:00
|
|
|
if (conv == INVALID_CONV)
|
|
|
|
return g_string_new (str);
|
2009-04-17 18:05:19 +04:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
buff = g_string_new ("");
|
2009-04-21 15:19:42 +04:00
|
|
|
str_nconvert (conv, str, len, buff);
|
2009-04-22 12:59:14 +04:00
|
|
|
str_close_conv (conv);
|
2009-04-17 18:05:19 +04:00
|
|
|
return buff;
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2002-10-31 02:14:26 +03:00
|
|
|
void
|
|
|
|
convert_from_input (char *str)
|
2001-05-31 05:27:20 +04:00
|
|
|
{
|
2018-01-21 11:39:17 +03:00
|
|
|
if (str != NULL)
|
|
|
|
for (; *str != '\0'; str++)
|
|
|
|
*str = conv_input[(unsigned char) *str];
|
2001-05-31 05:27:20 +04:00
|
|
|
}
|
2009-04-16 19:10:51 +04:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2009-04-21 15:19:42 +04:00
|
|
|
GString *
|
2016-03-29 10:39:41 +03:00
|
|
|
str_nconvert_to_input (const char *str, int len)
|
2009-04-17 18:05:19 +04:00
|
|
|
{
|
|
|
|
GString *buff;
|
|
|
|
GIConv conv;
|
|
|
|
|
2018-01-21 11:39:17 +03:00
|
|
|
if (str == NULL)
|
2023-05-21 13:07:23 +03:00
|
|
|
return NULL;
|
2009-04-17 18:05:19 +04:00
|
|
|
|
|
|
|
if (cp_display == cp_source)
|
2010-11-09 14:02:28 +03:00
|
|
|
return g_string_new (str);
|
2009-04-17 18:05:19 +04:00
|
|
|
|
2009-04-21 15:19:42 +04:00
|
|
|
conv = str_crt_conv_to (cp_source);
|
2024-09-13 12:29:37 +03:00
|
|
|
if (conv == INVALID_CONV)
|
|
|
|
return g_string_new (str);
|
2009-04-17 18:05:19 +04:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
buff = g_string_new ("");
|
2009-04-21 15:19:42 +04:00
|
|
|
str_nconvert (conv, str, len, buff);
|
2009-04-22 12:59:14 +04:00
|
|
|
str_close_conv (conv);
|
2009-04-17 18:05:19 +04:00
|
|
|
return buff;
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2009-04-16 19:10:51 +04:00
|
|
|
unsigned char
|
2009-04-17 01:26:08 +04:00
|
|
|
convert_from_utf_to_current (const char *str)
|
2009-04-16 19:10:51 +04:00
|
|
|
{
|
2013-10-15 10:15:57 +04:00
|
|
|
unsigned char buf_ch[UTF8_CHAR_LEN + 1];
|
2009-04-19 16:18:18 +04:00
|
|
|
unsigned char ch = '.';
|
2009-04-16 19:10:51 +04:00
|
|
|
GIConv conv;
|
2009-04-24 02:47:22 +04:00
|
|
|
const char *cp_to;
|
|
|
|
|
2015-04-19 13:57:38 +03:00
|
|
|
if (str == NULL)
|
2009-04-24 02:47:22 +04:00
|
|
|
return '.';
|
2009-04-16 19:10:51 +04:00
|
|
|
|
2011-02-10 18:02:54 +03:00
|
|
|
cp_to = get_codepage_id (mc_global.source_codepage);
|
2010-11-09 14:02:28 +03:00
|
|
|
conv = str_crt_conv_to (cp_to);
|
2009-04-16 19:10:51 +04:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
if (conv != INVALID_CONV)
|
|
|
|
{
|
|
|
|
switch (str_translate_char (conv, str, -1, (char *) buf_ch, sizeof (buf_ch)))
|
|
|
|
{
|
2009-04-22 20:35:32 +04:00
|
|
|
case ESTR_SUCCESS:
|
2009-04-18 18:50:05 +04:00
|
|
|
ch = buf_ch[0];
|
|
|
|
break;
|
2009-04-22 20:35:32 +04:00
|
|
|
case ESTR_PROBLEM:
|
|
|
|
case ESTR_FAILURE:
|
2009-04-16 19:10:51 +04:00
|
|
|
ch = '.';
|
2009-04-19 16:18:18 +04:00
|
|
|
break;
|
2015-04-19 13:57:38 +03:00
|
|
|
default:
|
|
|
|
break;
|
2009-04-16 19:10:51 +04:00
|
|
|
}
|
|
|
|
str_close_conv (conv);
|
|
|
|
}
|
2009-04-19 16:18:18 +04:00
|
|
|
|
2009-04-16 19:10:51 +04:00
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2009-04-17 01:26:08 +04:00
|
|
|
unsigned char
|
2016-03-29 10:39:41 +03:00
|
|
|
convert_from_utf_to_current_c (int input_char, GIConv conv)
|
2009-04-17 01:26:08 +04:00
|
|
|
{
|
2013-10-15 10:15:57 +04:00
|
|
|
unsigned char str[UTF8_CHAR_LEN + 1];
|
|
|
|
unsigned char buf_ch[UTF8_CHAR_LEN + 1];
|
2009-04-17 01:26:08 +04:00
|
|
|
unsigned char ch = '.';
|
2015-04-19 13:57:38 +03:00
|
|
|
int res;
|
2009-04-17 01:26:08 +04:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
res = g_unichar_to_utf8 (input_char, (char *) str);
|
|
|
|
if (res == 0)
|
2009-04-17 10:17:37 +04:00
|
|
|
return ch;
|
2015-04-19 13:57:38 +03:00
|
|
|
|
2009-04-22 01:27:42 +04:00
|
|
|
str[res] = '\0';
|
2009-04-17 01:26:08 +04:00
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
switch (str_translate_char (conv, (char *) str, -1, (char *) buf_ch, sizeof (buf_ch)))
|
|
|
|
{
|
2009-08-13 09:59:31 +04:00
|
|
|
case ESTR_SUCCESS:
|
|
|
|
ch = buf_ch[0];
|
|
|
|
break;
|
|
|
|
case ESTR_PROBLEM:
|
|
|
|
case ESTR_FAILURE:
|
|
|
|
ch = '.';
|
|
|
|
break;
|
2015-04-19 13:57:38 +03:00
|
|
|
default:
|
|
|
|
break;
|
2009-04-17 01:26:08 +04:00
|
|
|
}
|
2015-04-19 13:57:38 +03:00
|
|
|
|
2009-04-17 01:26:08 +04:00
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2009-04-20 00:28:00 +04:00
|
|
|
int
|
2016-03-29 10:39:41 +03:00
|
|
|
convert_from_8bit_to_utf_c (char input_char, GIConv conv)
|
2009-04-20 00:28:00 +04:00
|
|
|
{
|
|
|
|
unsigned char str[2];
|
2013-10-15 10:15:57 +04:00
|
|
|
unsigned char buf_ch[UTF8_CHAR_LEN + 1];
|
2015-04-19 13:57:38 +03:00
|
|
|
int ch;
|
2009-04-20 00:28:00 +04:00
|
|
|
|
|
|
|
str[0] = (unsigned char) input_char;
|
|
|
|
str[1] = '\0';
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
switch (str_translate_char (conv, (char *) str, -1, (char *) buf_ch, sizeof (buf_ch)))
|
|
|
|
{
|
2009-08-13 09:59:31 +04:00
|
|
|
case ESTR_SUCCESS:
|
2010-11-09 14:02:28 +03:00
|
|
|
{
|
2015-04-19 13:57:38 +03:00
|
|
|
int res;
|
|
|
|
|
|
|
|
res = g_utf8_get_char_validated ((char *) buf_ch, -1);
|
|
|
|
ch = res >= 0 ? res : buf_ch[0];
|
|
|
|
break;
|
2009-04-20 00:28:00 +04:00
|
|
|
}
|
2009-08-13 09:59:31 +04:00
|
|
|
case ESTR_PROBLEM:
|
|
|
|
case ESTR_FAILURE:
|
2015-04-19 13:57:38 +03:00
|
|
|
default:
|
2009-08-13 09:59:31 +04:00
|
|
|
ch = '.';
|
|
|
|
break;
|
2009-04-20 00:28:00 +04:00
|
|
|
}
|
2015-04-19 13:57:38 +03:00
|
|
|
|
2009-04-20 00:28:00 +04:00
|
|
|
return ch;
|
2009-04-20 13:01:47 +04:00
|
|
|
}
|
|
|
|
|
2010-11-09 14:02:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2009-04-20 13:01:47 +04:00
|
|
|
int
|
2016-03-29 10:39:41 +03:00
|
|
|
convert_from_8bit_to_utf_c2 (char input_char)
|
2009-04-20 13:01:47 +04:00
|
|
|
{
|
|
|
|
int ch = '.';
|
|
|
|
GIConv conv;
|
2009-04-24 02:47:22 +04:00
|
|
|
const char *cp_from;
|
2009-04-20 13:01:47 +04:00
|
|
|
|
2011-02-10 18:02:54 +03:00
|
|
|
cp_from = get_codepage_id (mc_global.source_codepage);
|
2009-04-20 13:01:47 +04:00
|
|
|
|
2018-01-21 12:00:34 +03:00
|
|
|
conv = str_crt_conv_to (cp_from);
|
2010-11-09 14:02:28 +03:00
|
|
|
if (conv != INVALID_CONV)
|
|
|
|
{
|
2018-01-21 12:00:34 +03:00
|
|
|
ch = convert_from_8bit_to_utf_c (input_char, conv);
|
2009-04-20 13:01:47 +04:00
|
|
|
str_close_conv (conv);
|
|
|
|
}
|
|
|
|
|
2015-04-19 13:57:38 +03:00
|
|
|
return ch;
|
2009-04-20 00:28:00 +04:00
|
|
|
}
|
2010-11-09 14:02:28 +03:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|