/* vi:set ts=8 sts=4 sw=4: * * VIM - Vi IMproved by Bram Moolenaar * Multibyte extensions partly by Sung-Hoon Baek * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. *//* * mbyte.c: Code specifically for handling multi-byte characters. * * The encoding used in the core is set with 'encoding'. When 'encoding' is * changed, the following four variables are set (for speed). * Currently these types of character encodings are supported: * * "enc_dbcs" When non-zero it tells the type of double byte character * encoding (Chinese, Korean, Japanese, etc.). * The cell width on the display is equal to the number of * bytes. (exception: DBCS_JPNU with first byte 0x8e) * Recognizing the first or second byte is difficult, it * requires checking a byte sequence from the start. * "enc_utf8" When TRUE use Unicode characters in UTF-8 encoding. * The cell width on the display needs to be determined from * the character value. * Recognizing bytes is easy: 0xxx.xxxx is a single-byte * char, 10xx.xxxx is a trailing byte, 11xx.xxxx is a leading * byte of a multi-byte character. * To make things complicated, up to two composing characters * are allowed. These are drawn on top of the first char. * For most editing the sequence of bytes with composing * characters included is considered to be one character. * "enc_unicode" When 2 use 16-bit Unicode characters (or UTF-16). * When 4 use 32-but Unicode characters. * Internally characters are stored in UTF-8 encoding to * avoid NUL bytes. Conversion happens when doing I/O. * "enc_utf8" will also be TRUE. * * "has_mbyte" is set when "enc_dbcs" or "enc_utf8" is non-zero. * * If none of these is TRUE, 8-bit bytes are used for a character. The * encoding isn't currently specified (TODO). * * 'encoding' specifies the encoding used in the core. This is in registers, * text manipulation, buffers, etc. Conversion has to be done when characters * in another encoding are received or send: * * clipboard * ^ * | (2) * V * +---------------+ * (1) | | (3) * keyboard ----->| core |-----> display * | | * +---------------+ * ^ * | (4) * V * file * * (1) Typed characters arrive in the current locale. Conversion is to be * done when 'encoding' is different from 'termencoding'. * (2) Text will be made available with the encoding specified with * 'encoding'. If this is not sufficient, system-specific conversion * might be required. * (3) For the GUI the correct font must be selected, no conversion done. * Otherwise, conversion is to be done when 'encoding' differs from * 'termencoding'. (Different in the GTK+ 2 port -- 'termencoding' * is always used for both input and output and must always be set to * "utf-8". gui_mch_init() does this automatically.) * (4) The encoding of the file is specified with 'fileencoding'. Conversion * is to be done when it's different from 'encoding'. * * The viminfo file is a special case: Only text is converted, not file names. * Vim scripts may contain an ":encoding" command. This has an effect for * some commands, like ":menutrans" */ #include "vim.h" #ifdef WIN32UNIX# ifndef WIN32_LEAN_AND_MEAN# define WIN32_LEAN_AND_MEAN# endif# include <windows.h># ifdef WIN32# undef WIN32 /* Some windows.h define WIN32, we don't want that here. */# endif#endif #if (defined(WIN3264) || defined(WIN32UNIX)) && !defined(__MINGW32__)# include <winnls.h>#endif #ifdef FEAT_GUI_X11# include <X11/Intrinsic.h>#endif#ifdef X_LOCALE#include <X11/Xlocale.h>#endif #if defined(FEAT_GUI_GTK) && defined(FEAT_XIM) && defined(HAVE_GTK2)# include <gdk/gdkkeysyms.h># ifdef WIN3264# include <gdk/gdkwin32.h># else# include <gdk/gdkx.h># endif#endif #ifdef HAVE_WCHAR_H# include <wchar.h>#endif #if 0/* This has been disabled, because several people reported problems with the * wcwidth() and iswprint() library functions, esp. for Hebrew. */# ifdef __STDC_ISO_10646__# define USE_WCHAR_FUNCTIONS# endif#endif #if defined(FEAT_MBYTE) || defined(PROTO) static int enc_canon_search __ARGS((char_u *name));static int dbcs_char2len __ARGS((int c));static int dbcs_char2bytes __ARGS((int c, char_u *buf));static int dbcs_ptr2len __ARGS((char_u *p));static int dbcs_char2cells __ARGS((int c));static int dbcs_ptr2char __ARGS((char_u *p)); /* Lookup table to quickly get the length in bytes of a UTF-8 character from * the first byte of a UTF-8 string. Bytes which are illegal when used as the * first byte have a one, because these will be used separately. */static char utf8len_tab[256] ={ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*bogus*/ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*bogus*/ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,}; /* * XIM often causes trouble. Define XIM_DEBUG to get a log of XIM callbacks * in the "xim.log" file. *//* #define XIM_DEBUG */#ifdef XIM_DEBUG static voidxim_log(char *s, ...){ va_list arglist; static FILE *fd = NULL; if (fd == (FILE *)-1) return; if (fd == NULL) { fd = mch_fopen("xim.log", "w"); if (fd == NULL) { EMSG("Cannot open xim.log"); fd = (FILE *)-1; return; } } va_start(arglist, s); vfprintf(fd, s, arglist); va_end(arglist);}#endif #endif #if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT) || defined(PROTO)/* * Canonical encoding names and their properties. * "iso-8859-n" is handled by enc_canonize() directly. */static struct{ char *name; int prop; int codepage;}enc_canon_table[] ={#define IDX_LATIN_1 0 {"latin1", ENC_8BIT + ENC_LATIN1, 1252},#define IDX_ISO_2 1 {"iso-8859-2", ENC_8BIT, 0},#define IDX_ISO_3 2 {"iso-8859-3", ENC_8BIT, 0},#define IDX_ISO_4 3 {"iso-8859-4", ENC_8BIT, 0},#define IDX_ISO_5 4 {"iso-8859-5", ENC_8BIT, 0},#define IDX_ISO_6 5 {"iso-8859-6", ENC_8BIT, 0},#define IDX_ISO_7 6 {"iso-8859-7", ENC_8BIT, 0},#define IDX_ISO_8 7 {"iso-8859-8", ENC_8BIT, 0},#define IDX_ISO_9 8 {"iso-8859-9", ENC_8BIT, 0},#define IDX_ISO_10 9 {"iso-8859-10", ENC_8BIT, 0},#define IDX_ISO_11 10 {"iso-8859-11", ENC_8BIT, 0},#define IDX_ISO_13 11 {"iso-8859-13", ENC_8BIT, 0},#define IDX_ISO_14 12 {"iso-8859-14", ENC_8BIT, 0},#define IDX_ISO_15 13 {"iso-8859-15", ENC_8BIT + ENC_LATIN9, 0},#define IDX_KOI8_R 14 {"koi8-r", ENC_8BIT, 0},#define IDX_KOI8_U 15 {"koi8-u", ENC_8BIT, 0},#define IDX_UTF8 16 {"utf-8", ENC_UNICODE, 0},#define IDX_UCS2 17 {"ucs-2", ENC_UNICODE + ENC_ENDIAN_B + ENC_2BYTE, 0},#define IDX_UCS2LE 18 {"ucs-2le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2BYTE, 0},#define IDX_UTF16 19 {"utf-16", ENC_UNICODE + ENC_ENDIAN_B + ENC_2WORD, 0},#define IDX_UTF16LE 20 {"utf-16le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2WORD, 0},#define IDX_UCS4 21 {"ucs-4", ENC_UNICODE + ENC_ENDIAN_B + ENC_4BYTE, 0},#define IDX_UCS4LE 22 {"ucs-4le", ENC_UNICODE + ENC_ENDIAN_L + ENC_4BYTE, 0}, /* For debugging DBCS encoding on Unix. */#define IDX_DEBUG 23 {"debug", ENC_DBCS, DBCS_DEBUG},#define IDX_EUC_JP 24 {"euc-jp", ENC_DBCS, DBCS_JPNU},#define IDX_SJIS 25 {"sjis", ENC_DBCS, DBCS_JPN},#define IDX_EUC_KR 26 {"euc-kr", ENC_DBCS, DBCS_KORU},#define IDX_EUC_CN 27 {"euc-cn", ENC_DBCS, DBCS_CHSU},#define IDX_EUC_TW 28 {"euc-tw", ENC_DBCS, DBCS_CHTU},#define IDX_BIG5 29 {"big5", ENC_DBCS, DBCS_CHT}, /* MS-DOS and MS-Windows codepages are included here, so that they can be * used on Unix too. Most of them are similar to ISO-8859 encodings, but * not exactly the same. */#define IDX_CP437 30 {"cp437", ENC_8BIT, 437}, /* like iso-8859-1 */#define IDX_CP737 31 {"cp737", ENC_8BIT, 737}, /* like iso-8859-7 */#define IDX_CP775 32 {"cp775", ENC_8BIT, 775}, /* Baltic */#define IDX_CP850 33 {"cp850", ENC_8BIT, 850}, /* like iso-8859-4 */#define IDX_CP852 34 {"cp852", ENC_8BIT, 852}, /* like iso-8859-1 */#define IDX_CP855 35 {"cp855", ENC_8BIT, 855}, /* like iso-8859-2 */#define IDX_CP857 36 {"cp857", ENC_8BIT, 857}, /* like iso-8859-5 */#define IDX_CP860 37 {"cp860", ENC_8BIT, 860}, /* like iso-8859-9 */#define IDX_CP861 38 {"cp861", ENC_8BIT, 861}, /* like iso-8859-1 */#define IDX_CP862 39 {"cp862", ENC_8BIT, 862}, /* like iso-8859-1 */#define IDX_CP863 40 {"cp863", ENC_8BIT, 863}, /* like iso-8859-8 */#define IDX_CP865 41 {"cp865", ENC_8BIT, 865}, /* like iso-8859-1 */#define IDX_CP866 42 {"cp866", ENC_8BIT, 866}, /* like iso-8859-5 */#define IDX_CP869 43 {"cp869", ENC_8BIT, 869}, /* like iso-8859-7 */#define IDX_CP874 44 {"cp874", ENC_8BIT, 874}, /* Thai */#define IDX_CP932 45 {"cp932", ENC_DBCS, DBCS_JPN},#define IDX_CP936 46 {"cp936", ENC_DBCS, DBCS_CHS},#define IDX_CP949 47 {"cp949", ENC_DBCS, DBCS_KOR},#define IDX_CP950 48 {"cp950", ENC_DBCS, DBCS_CHT},#define IDX_CP1250 49 {"cp1250", ENC_8BIT, 1250}, /* Czech, Polish, etc. */#define IDX_CP1251 50 {"cp1251", ENC_8BIT, 1251}, /* Cyrillic */ /* cp1252 is considered to be equal to latin1 */#define IDX_CP1253 51 {"cp1253", ENC_8BIT, 1253}, /* Greek */#define IDX_CP1254 52 {"cp1254", ENC_8BIT, 1254}, /* Turkish */#define IDX_CP1255 53 {"cp1255", ENC_8BIT, 1255}, /* Hebrew */#define IDX_CP1256 54 {"cp1256", ENC_8BIT, 1256}, /* Arabic */#define IDX_CP1257 55 {"cp1257", ENC_8BIT, 1257}, /* Baltic */#define IDX_CP1258 56 {"cp1258", ENC_8BIT, 1258}, /* Vietnamese */ #define IDX_MACROMAN 57 {"macroman", ENC_8BIT + ENC_MACROMAN, 0}, /* Mac OS */#define IDX_DECMCS 58 {"dec-mcs", ENC_8BIT, 0}, /* DEC MCS */#define IDX_HPROMAN8 59 {"hp-roman8", ENC_8BIT, 0}, /* HP Roman8 */#define IDX_COUNT 60}; /* * Aliases for encoding names. */static struct{ char *name; int canon;}enc_alias_table[] ={ {"ansi", IDX_LATIN_1}, {"iso-8859-1", IDX_LATIN_1}, {"latin2", IDX_ISO_2}, {"latin3", IDX_ISO_3}, {"latin4", IDX_ISO_4}, {"cyrillic", IDX_ISO_5}, {"arabic", IDX_ISO_6}, {"greek", IDX_ISO_7},#ifdef WIN3264 {"hebrew", IDX_CP1255},#else {"hebrew", IDX_ISO_8},#endif {"latin5", IDX_ISO_9}, {"turkish", IDX_ISO_9}, /* ? */ {"latin6", IDX_ISO_10}, {"nordic", IDX_ISO_10}, /* ? */ {"thai", IDX_ISO_11}, /* ? */ {"latin7", IDX_ISO_13}, {"latin8", IDX_ISO_14}, {"latin9", IDX_ISO_15}, {"utf8", IDX_UTF8}, {"unicode", IDX_UCS2}, {"ucs2", IDX_UCS2}, {"ucs2be", IDX_UCS2}, {"ucs-2be", IDX_UCS2}, {"ucs2le", IDX_UCS2LE}, {"utf16", IDX_UTF16}, {"utf16be", IDX_UTF16}, {"utf-16be", IDX_UTF16}, {"utf16le", IDX_UTF16LE}, {"ucs4", IDX_UCS4}, {"ucs4be", IDX_UCS4}, {"ucs-4be", IDX_UCS4}, {"ucs4le", IDX_UCS4LE}, {"932", IDX_CP932}, {"949", IDX_CP949}, {"936", IDX_CP936}, {"gbk", IDX_CP936}, {"950", IDX_CP950}, {"eucjp", IDX_EUC_JP}, {"unix-jis", IDX_EUC_JP}, {"ujis", IDX_EUC_JP}, {"shift-jis", IDX_SJIS}, {"euckr", IDX_EUC_KR}, {"5601", IDX_EUC_KR}, /* Sun: KS C 5601 */ {"euccn", IDX_EUC_CN}, {"gb2312", IDX_EUC_CN}, {"euctw", IDX_EUC_TW},#if defined(WIN3264) || defined(WIN32UNIX) || defined(MACOS) {"japan", IDX_CP932}, {"korea", IDX_CP949}, {"prc", IDX_CP936}, {"chinese", IDX_CP936}, {"taiwan", IDX_CP950}, {"big5", IDX_CP950},#else {"japan", IDX_EUC_JP}, {"korea", IDX_EUC_KR}, {"prc", IDX_EUC_CN}, {"chinese", IDX_EUC_CN}, {"taiwan", IDX_EUC_TW}, {"cp950", IDX_BIG5}, {"950", IDX_BIG5},#endif {"mac", IDX_MACROMAN}, {"mac-roman", IDX_MACROMAN}, {NULL, 0}}; #ifndef CP_UTF8# define CP_UTF8 65001 /* magic number from winnls.h */#endif /* * Find encoding "name" in the list of canonical encoding names. * Returns -1 if not found. */ static intenc_canon_search(name) char_u *name;{ int i; for (i = 0; i < IDX_COUNT; ++i) if (STRCMP(name, enc_canon_table[i].name) == 0) return i; return -1;} #endif #if defined(FEAT_MBYTE) || defined(PROTO) /* * Find canonical encoding "name" in the list and return its properties. * Returns 0 if not found. */ intenc_canon_props(name) char_u *name;{ int i; i = enc_canon_search(name); if (i >= 0) return enc_canon_table[i].prop;#ifdef WIN3264 if (name[0] == 'c' && name[1] == 'p' && VIM_ISDIGIT(name[2])) { CPINFO cpinfo; /* Get info on this codepage to find out what it is. */ if (GetCPInfo(atoi(name + 2), &cpinfo) != 0) { if (cpinfo.MaxCharSize == 1) /* some single-byte encoding */ return ENC_8BIT; if (cpinfo.MaxCharSize == 2 && (cpinfo.LeadByte[0] != 0 || cpinfo.LeadByte[1] != 0)) /* must be a DBCS encoding */ return ENC_DBCS; } return 0; }#endif if (STRNCMP(name, "2byte-", 6) == 0) return ENC_DBCS; if (STRNCMP(name, "8bit-", 5) == 0 || STRNCMP(name, "iso-8859-", 9) == 0) return ENC_8BIT; return 0;} /* * Set up for using multi-byte characters. * Called in three cases: * - by main() to initialize (p_enc == NULL) * - by set_init_1() after 'encoding' was set to its default. * - by do_set() when 'encoding' has been set. * p_enc must have been passed through enc_canonize() already. * Sets the "enc_unicode", "enc_utf8", "enc_dbcs" and "has_mbyte" flags. * Fills mb_bytelen_tab[] and returns NULL when there are no problems. * When there is something wrong: Returns an error message and doesn't change * anything. */ char_u *mb_init(){ int i; int idx; int n; int enc_dbcs_new = 0;#if defined(USE_ICONV) && !defined(WIN3264) && !defined(WIN32UNIX) \ && !defined(MACOS)# define LEN_FROM_CONV vimconv_T vimconv; char_u *p;#endif if (p_enc == NULL) { /* Just starting up: set the whole table to one's. */ for (i = 0; i < 256; ++i) mb_bytelen_tab[i] = 1; input_conv.vc_type = CONV_NONE; input_conv.vc_factor = 1; output_conv.vc_type = CONV_NONE; return NULL; } #ifdef WIN3264 if (p_enc[0] == 'c' && p_enc[1] == 'p' && VIM_ISDIGIT(p_enc[2])) { CPINFO cpinfo;Lines 1–500 of 6106. Load more
/* vi:set ts=8 sts=4 sw=4: * * VIM - Vi IMproved by Bram Moolenaar * Multibyte extensions partly by Sung-Hoon Baek * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ /* * mbyte.c: Code specifically for handling multi-byte characters. * * The encoding used in the core is set with 'encoding'. When 'encoding' is * changed, the following four variables are set (for speed). * Currently these types of character encodings are supported: * * "enc_dbcs" When non-zero it tells the type of double byte character * encoding (Chinese, Korean, Japanese, etc.). * The cell width on the display is equal to the number of * bytes. (exception: DBCS_JPNU with first byte 0x8e) * Recognizing the first or second byte is difficult, it * requires checking a byte sequence from the start. * "enc_utf8" When TRUE use Unicode characters in UTF-8 encoding. * The cell width on the display needs to be determined from * the character value. * Recognizing bytes is easy: 0xxx.xxxx is a single-byte * char, 10xx.xxxx is a trailing byte, 11xx.xxxx is a leading * byte of a multi-byte character. * To make things complicated, up to two composing characters * are allowed. These are drawn on top of the first char. * For most editing the sequence of bytes with composing * characters included is considered to be one character. * "enc_unicode" When 2 use 16-bit Unicode characters (or UTF-16). * When 4 use 32-but Unicode characters. * Internally characters are stored in UTF-8 encoding to * avoid NUL bytes. Conversion happens when doing I/O. * "enc_utf8" will also be TRUE. * * "has_mbyte" is set when "enc_dbcs" or "enc_utf8" is non-zero. * * If none of these is TRUE, 8-bit bytes are used for a character. The * encoding isn't currently specified (TODO). * * 'encoding' specifies the encoding used in the core. This is in registers, * text manipulation, buffers, etc. Conversion has to be done when characters * in another encoding are received or send: * * clipboard * ^ * | (2) * V * +---------------+ * (1) | | (3) * keyboard ----->| core |-----> display * | | * +---------------+ * ^ * | (4) * V * file * * (1) Typed characters arrive in the current locale. Conversion is to be * done when 'encoding' is different from 'termencoding'. * (2) Text will be made available with the encoding specified with * 'encoding'. If this is not sufficient, system-specific conversion * might be required. * (3) For the GUI the correct font must be selected, no conversion done. * Otherwise, conversion is to be done when 'encoding' differs from * 'termencoding'. (Different in the GTK+ 2 port -- 'termencoding' * is always used for both input and output and must always be set to * "utf-8". gui_mch_init() does this automatically.) * (4) The encoding of the file is specified with 'fileencoding'. Conversion * is to be done when it's different from 'encoding'. * * The viminfo file is a special case: Only text is converted, not file names. * Vim scripts may contain an ":encoding" command. This has an effect for * some commands, like ":menutrans" */ #include "vim.h" #ifdef WIN32UNIX # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif # include <windows.h> # ifdef WIN32 # undef WIN32 /* Some windows.h define WIN32, we don't want that here. */ # endif #endif #if (defined(WIN3264) || defined(WIN32UNIX)) && !defined(__MINGW32__) # include <winnls.h> #endif #ifdef FEAT_GUI_X11 # include <X11/Intrinsic.h> #endif #ifdef X_LOCALE #include <X11/Xlocale.h> #endif #if defined(FEAT_GUI_GTK) && defined(FEAT_XIM) && defined(HAVE_GTK2) # include <gdk/gdkkeysyms.h> # ifdef WIN3264 # include <gdk/gdkwin32.h> # else # include <gdk/gdkx.h> # endif #endif #ifdef HAVE_WCHAR_H # include <wchar.h> #endif #if 0 /* This has been disabled, because several people reported problems with the * wcwidth() and iswprint() library functions, esp. for Hebrew. */ # ifdef __STDC_ISO_10646__ # define USE_WCHAR_FUNCTIONS # endif #endif #if defined(FEAT_MBYTE) || defined(PROTO) static int enc_canon_search __ARGS((char_u *name)); static int dbcs_char2len __ARGS((int c)); static int dbcs_char2bytes __ARGS((int c, char_u *buf)); static int dbcs_ptr2len __ARGS((char_u *p)); static int dbcs_char2cells __ARGS((int c)); static int dbcs_ptr2char __ARGS((char_u *p)); /* Lookup table to quickly get the length in bytes of a UTF-8 character from * the first byte of a UTF-8 string. Bytes which are illegal when used as the * first byte have a one, because these will be used separately. */ static char utf8len_tab[256] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*bogus*/ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*bogus*/ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1, }; /* * XIM often causes trouble. Define XIM_DEBUG to get a log of XIM callbacks * in the "xim.log" file. */ /* #define XIM_DEBUG */ #ifdef XIM_DEBUG static void xim_log(char *s, ...) { va_list arglist; static FILE *fd = NULL; if (fd == (FILE *)-1) return; if (fd == NULL) { fd = mch_fopen("xim.log", "w"); if (fd == NULL) { EMSG("Cannot open xim.log"); fd = (FILE *)-1; return; } } va_start(arglist, s); vfprintf(fd, s, arglist); va_end(arglist); } #endif #endif #if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT) || defined(PROTO) /* * Canonical encoding names and their properties. * "iso-8859-n" is handled by enc_canonize() directly. */ static struct { char *name; int prop; int codepage;} enc_canon_table[] = { #define IDX_LATIN_1 0 {"latin1", ENC_8BIT + ENC_LATIN1, 1252}, #define IDX_ISO_2 1 {"iso-8859-2", ENC_8BIT, 0}, #define IDX_ISO_3 2 {"iso-8859-3", ENC_8BIT, 0}, #define IDX_ISO_4 3 {"iso-8859-4", ENC_8BIT, 0}, #define IDX_ISO_5 4 {"iso-8859-5", ENC_8BIT, 0}, #define IDX_ISO_6 5 {"iso-8859-6", ENC_8BIT, 0}, #define IDX_ISO_7 6 {"iso-8859-7", ENC_8BIT, 0}, #define IDX_ISO_8 7 {"iso-8859-8", ENC_8BIT, 0}, #define IDX_ISO_9 8 {"iso-8859-9", ENC_8BIT, 0}, #define IDX_ISO_10 9 {"iso-8859-10", ENC_8BIT, 0}, #define IDX_ISO_11 10 {"iso-8859-11", ENC_8BIT, 0}, #define IDX_ISO_13 11 {"iso-8859-13", ENC_8BIT, 0}, #define IDX_ISO_14 12 {"iso-8859-14", ENC_8BIT, 0}, #define IDX_ISO_15 13 {"iso-8859-15", ENC_8BIT + ENC_LATIN9, 0}, #define IDX_KOI8_R 14 {"koi8-r", ENC_8BIT, 0}, #define IDX_KOI8_U 15 {"koi8-u", ENC_8BIT, 0}, #define IDX_UTF8 16 {"utf-8", ENC_UNICODE, 0}, #define IDX_UCS2 17 {"ucs-2", ENC_UNICODE + ENC_ENDIAN_B + ENC_2BYTE, 0}, #define IDX_UCS2LE 18 {"ucs-2le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2BYTE, 0}, #define IDX_UTF16 19 {"utf-16", ENC_UNICODE + ENC_ENDIAN_B + ENC_2WORD, 0}, #define IDX_UTF16LE 20 {"utf-16le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2WORD, 0}, #define IDX_UCS4 21 {"ucs-4", ENC_UNICODE + ENC_ENDIAN_B + ENC_4BYTE, 0}, #define IDX_UCS4LE 22 {"ucs-4le", ENC_UNICODE + ENC_ENDIAN_L + ENC_4BYTE, 0}, /* For debugging DBCS encoding on Unix. */ #define IDX_DEBUG 23 {"debug", ENC_DBCS, DBCS_DEBUG}, #define IDX_EUC_JP 24 {"euc-jp", ENC_DBCS, DBCS_JPNU}, #define IDX_SJIS 25 {"sjis", ENC_DBCS, DBCS_JPN}, #define IDX_EUC_KR 26 {"euc-kr", ENC_DBCS, DBCS_KORU}, #define IDX_EUC_CN 27 {"euc-cn", ENC_DBCS, DBCS_CHSU}, #define IDX_EUC_TW 28 {"euc-tw", ENC_DBCS, DBCS_CHTU}, #define IDX_BIG5 29 {"big5", ENC_DBCS, DBCS_CHT}, /* MS-DOS and MS-Windows codepages are included here, so that they can be * used on Unix too. Most of them are similar to ISO-8859 encodings, but * not exactly the same. */ #define IDX_CP437 30 {"cp437", ENC_8BIT, 437}, /* like iso-8859-1 */ #define IDX_CP737 31 {"cp737", ENC_8BIT, 737}, /* like iso-8859-7 */ #define IDX_CP775 32 {"cp775", ENC_8BIT, 775}, /* Baltic */ #define IDX_CP850 33 {"cp850", ENC_8BIT, 850}, /* like iso-8859-4 */ #define IDX_CP852 34 {"cp852", ENC_8BIT, 852}, /* like iso-8859-1 */ #define IDX_CP855 35 {"cp855", ENC_8BIT, 855}, /* like iso-8859-2 */ #define IDX_CP857 36 {"cp857", ENC_8BIT, 857}, /* like iso-8859-5 */ #define IDX_CP860 37 {"cp860", ENC_8BIT, 860}, /* like iso-8859-9 */ #define IDX_CP861 38 {"cp861", ENC_8BIT, 861}, /* like iso-8859-1 */ #define IDX_CP862 39 {"cp862", ENC_8BIT, 862}, /* like iso-8859-1 */ #define IDX_CP863 40 {"cp863", ENC_8BIT, 863}, /* like iso-8859-8 */ #define IDX_CP865 41 {"cp865", ENC_8BIT, 865}, /* like iso-8859-1 */ #define IDX_CP866 42 {"cp866", ENC_8BIT, 866}, /* like iso-8859-5 */ #define IDX_CP869 43 {"cp869", ENC_8BIT, 869}, /* like iso-8859-7 */ #define IDX_CP874 44 {"cp874", ENC_8BIT, 874}, /* Thai */ #define IDX_CP932 45 {"cp932", ENC_DBCS, DBCS_JPN}, #define IDX_CP936 46 {"cp936", ENC_DBCS, DBCS_CHS}, #define IDX_CP949 47 {"cp949", ENC_DBCS, DBCS_KOR}, #define IDX_CP950 48 {"cp950", ENC_DBCS, DBCS_CHT}, #define IDX_CP1250 49 {"cp1250", ENC_8BIT, 1250}, /* Czech, Polish, etc. */ #define IDX_CP1251 50 {"cp1251", ENC_8BIT, 1251}, /* Cyrillic */ /* cp1252 is considered to be equal to latin1 */ #define IDX_CP1253 51 {"cp1253", ENC_8BIT, 1253}, /* Greek */ #define IDX_CP1254 52 {"cp1254", ENC_8BIT, 1254}, /* Turkish */ #define IDX_CP1255 53 {"cp1255", ENC_8BIT, 1255}, /* Hebrew */ #define IDX_CP1256 54 {"cp1256", ENC_8BIT, 1256}, /* Arabic */ #define IDX_CP1257 55 {"cp1257", ENC_8BIT, 1257}, /* Baltic */ #define IDX_CP1258 56 {"cp1258", ENC_8BIT, 1258}, /* Vietnamese */ #define IDX_MACROMAN 57 {"macroman", ENC_8BIT + ENC_MACROMAN, 0}, /* Mac OS */ #define IDX_DECMCS 58 {"dec-mcs", ENC_8BIT, 0}, /* DEC MCS */ #define IDX_HPROMAN8 59 {"hp-roman8", ENC_8BIT, 0}, /* HP Roman8 */ #define IDX_COUNT 60 }; /* * Aliases for encoding names. */ static struct { char *name; int canon;} enc_alias_table[] = { {"ansi", IDX_LATIN_1}, {"iso-8859-1", IDX_LATIN_1}, {"latin2", IDX_ISO_2}, {"latin3", IDX_ISO_3}, {"latin4", IDX_ISO_4}, {"cyrillic", IDX_ISO_5}, {"arabic", IDX_ISO_6}, {"greek", IDX_ISO_7}, #ifdef WIN3264 {"hebrew", IDX_CP1255}, #else {"hebrew", IDX_ISO_8}, #endif {"latin5", IDX_ISO_9}, {"turkish", IDX_ISO_9}, /* ? */ {"latin6", IDX_ISO_10}, {"nordic", IDX_ISO_10}, /* ? */ {"thai", IDX_ISO_11}, /* ? */ {"latin7", IDX_ISO_13}, {"latin8", IDX_ISO_14}, {"latin9", IDX_ISO_15}, {"utf8", IDX_UTF8}, {"unicode", IDX_UCS2}, {"ucs2", IDX_UCS2}, {"ucs2be", IDX_UCS2}, {"ucs-2be", IDX_UCS2}, {"ucs2le", IDX_UCS2LE}, {"utf16", IDX_UTF16}, {"utf16be", IDX_UTF16}, {"utf-16be", IDX_UTF16}, {"utf16le", IDX_UTF16LE}, {"ucs4", IDX_UCS4}, {"ucs4be", IDX_UCS4}, {"ucs-4be", IDX_UCS4}, {"ucs4le", IDX_UCS4LE}, {"932", IDX_CP932}, {"949", IDX_CP949}, {"936", IDX_CP936}, {"gbk", IDX_CP936}, {"950", IDX_CP950}, {"eucjp", IDX_EUC_JP}, {"unix-jis", IDX_EUC_JP}, {"ujis", IDX_EUC_JP}, {"shift-jis", IDX_SJIS}, {"euckr", IDX_EUC_KR}, {"5601", IDX_EUC_KR}, /* Sun: KS C 5601 */ {"euccn", IDX_EUC_CN}, {"gb2312", IDX_EUC_CN}, {"euctw", IDX_EUC_TW}, #if defined(WIN3264) || defined(WIN32UNIX) || defined(MACOS) {"japan", IDX_CP932}, {"korea", IDX_CP949}, {"prc", IDX_CP936}, {"chinese", IDX_CP936}, {"taiwan", IDX_CP950}, {"big5", IDX_CP950}, #else {"japan", IDX_EUC_JP}, {"korea", IDX_EUC_KR}, {"prc", IDX_EUC_CN}, {"chinese", IDX_EUC_CN}, {"taiwan", IDX_EUC_TW}, {"cp950", IDX_BIG5}, {"950", IDX_BIG5}, #endif {"mac", IDX_MACROMAN}, {"mac-roman", IDX_MACROMAN}, {NULL, 0} }; #ifndef CP_UTF8 # define CP_UTF8 65001 /* magic number from winnls.h */ #endif /* * Find encoding "name" in the list of canonical encoding names. * Returns -1 if not found. */ static int enc_canon_search(name) char_u *name; { int i; for (i = 0; i < IDX_COUNT; ++i) if (STRCMP(name, enc_canon_table[i].name) == 0) return i; return -1; } #endif #if defined(FEAT_MBYTE) || defined(PROTO) /* * Find canonical encoding "name" in the list and return its properties. * Returns 0 if not found. */ int enc_canon_props(name) char_u *name; { int i; i = enc_canon_search(name); if (i >= 0) return enc_canon_table[i].prop; #ifdef WIN3264 if (name[0] == 'c' && name[1] == 'p' && VIM_ISDIGIT(name[2])) { CPINFO cpinfo; /* Get info on this codepage to find out what it is. */ if (GetCPInfo(atoi(name + 2), &cpinfo) != 0) { if (cpinfo.MaxCharSize == 1) /* some single-byte encoding */ return ENC_8BIT; if (cpinfo.MaxCharSize == 2 && (cpinfo.LeadByte[0] != 0 || cpinfo.LeadByte[1] != 0)) /* must be a DBCS encoding */ return ENC_DBCS; } return 0; } #endif if (STRNCMP(name, "2byte-", 6) == 0) return ENC_DBCS; if (STRNCMP(name, "8bit-", 5) == 0 || STRNCMP(name, "iso-8859-", 9) == 0) return ENC_8BIT; return 0; } /* * Set up for using multi-byte characters. * Called in three cases: * - by main() to initialize (p_enc == NULL) * - by set_init_1() after 'encoding' was set to its default. * - by do_set() when 'encoding' has been set. * p_enc must have been passed through enc_canonize() already. * Sets the "enc_unicode", "enc_utf8", "enc_dbcs" and "has_mbyte" flags. * Fills mb_bytelen_tab[] and returns NULL when there are no problems. * When there is something wrong: Returns an error message and doesn't change * anything. */ char_u * mb_init() { int i; int idx; int n; int enc_dbcs_new = 0; #if defined(USE_ICONV) && !defined(WIN3264) && !defined(WIN32UNIX) \ && !defined(MACOS) # define LEN_FROM_CONV vimconv_T vimconv; char_u *p; #endif if (p_enc == NULL) { /* Just starting up: set the whole table to one's. */ for (i = 0; i < 256; ++i) mb_bytelen_tab[i] = 1; input_conv.vc_type = CONV_NONE; input_conv.vc_factor = 1; output_conv.vc_type = CONV_NONE; return NULL; } #ifdef WIN3264 if (p_enc[0] == 'c' && p_enc[1] == 'p' && VIM_ISDIGIT(p_enc[2])) { CPINFO cpinfo;