mirror of
https://github.com/vim/vim
synced 2025-04-30 13:27:47 +02:00
612 lines
17 KiB
C
612 lines
17 KiB
C
/* vi:set ts=8 sts=4 sw=4:
|
|
*
|
|
* VIM - Vi IMproved by Bram Moolenaar
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
* os_macosx.c -- election of os_mac.c or os_unix.c
|
|
*
|
|
*/
|
|
|
|
#ifdef MACOS_X_UNIX
|
|
# ifdef HAVE_CONFIG_H /* Using Makefile. */
|
|
# include "vim.h"
|
|
# else
|
|
# include "os_unix.c" /* Using Project Builder */
|
|
# endif
|
|
#else
|
|
# include "os_mac.c"
|
|
# include <TextEncodingConverter.h>
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
void
|
|
Trace(char* fmt, ...)
|
|
{
|
|
char buf[2048];
|
|
va_list args;
|
|
|
|
va_start(args, fmt);
|
|
/* vsnprintf(buf, sizeof(buf), fmt, args);*/
|
|
fprintf(stderr, "%s", buf);
|
|
va_end(args);
|
|
}
|
|
#endif
|
|
|
|
#ifdef MACOS_X_ICONVEMU
|
|
/*
|
|
* Libiconv emulation layer
|
|
*/
|
|
|
|
struct _iconv_t
|
|
{
|
|
TECObjectRef tec;
|
|
TECObjectRef tecReverse;
|
|
TECSnifferObjectRef sniff;
|
|
TextEncoding from;
|
|
TextEncoding to;
|
|
};
|
|
/* typedef struct _iconv_t *iconv_t; */
|
|
|
|
|
|
static int last_errno = 0;
|
|
|
|
/*
|
|
* Get TextEncoding from iconv's encoding name
|
|
*/
|
|
static TextEncoding
|
|
get_textencoding(const char* encodename)
|
|
{
|
|
static struct {
|
|
const char* name;
|
|
TextEncoding encode;
|
|
} encodetable[] = {
|
|
/* ISO-8859 encodings family */
|
|
{"latin1", kTextEncodingISOLatin1},
|
|
{"latin2", kTextEncodingISOLatin2},
|
|
{"latin3", kTextEncodingISOLatin3},
|
|
{"latin4", kTextEncodingISOLatin4},
|
|
{"latin5", kTextEncodingISOLatin5},
|
|
{"latin6", kTextEncodingISOLatin6},
|
|
{"latin7", kTextEncodingISOLatin7},
|
|
{"latin8", kTextEncodingISOLatin8},
|
|
{"latin9", kTextEncodingISOLatin9},
|
|
{"iso-8859-1", kTextEncodingISOLatin1},
|
|
{"iso-8859-2", kTextEncodingISOLatin2},
|
|
{"iso-8859-3", kTextEncodingISOLatin3},
|
|
{"iso-8859-4", kTextEncodingISOLatin4},
|
|
{"iso-8859-5", kTextEncodingISOLatinCyrillic},
|
|
{"iso-8859-6", kTextEncodingISOLatinArabic},
|
|
{"iso-8859-7", kTextEncodingISOLatinGreek},
|
|
{"iso-8859-8", kTextEncodingISOLatinHebrew},
|
|
{"iso-8859-9", kTextEncodingISOLatin5},
|
|
{"iso-8859-10", kTextEncodingISOLatin6},
|
|
|
|
/* Unicode encodings. */
|
|
/* TODO: Add other type of unicode */
|
|
{"ucs-2", kTextEncodingMacUnicode},
|
|
|
|
/* Japanese encoding aliases */
|
|
{"cp932", kTextEncodingShiftJIS},
|
|
{"shift-jis", kTextEncodingShiftJIS},
|
|
{"euc-jp", kTextEncodingEUC_JP},
|
|
{"iso-2022-jp", kTextEncodingISO_2022_JP},
|
|
{"iso-2022-jp-1", kTextEncodingISO_2022_JP_1},
|
|
{"iso-2022-jp-2", kTextEncodingISO_2022_JP_2},
|
|
{"iso-2022-jp-3", kTextEncodingISO_2022_JP_3},
|
|
|
|
/* Other aliases. These aliases in this block are just guessed. */
|
|
/* TODO: Must be verified. */
|
|
{"gb2312", kTextEncodingGB_2312_80},
|
|
{"cp936", kTextEncodingMacChineseSimp},
|
|
{"euc-cn", kTextEncodingEUC_CN},
|
|
{"cp950", kTextEncodingMacChineseTrad},
|
|
{"euc-tw", kTextEncodingEUC_TW},
|
|
{"cp949", kTextEncodingMacKorean},
|
|
{"euc-kr", kTextEncodingEUC_KR},
|
|
|
|
/*
|
|
* All encodings supported by Macintosh. You can find these values
|
|
* in a file:
|
|
* /System/Library/Frameworks/CoreServices.framework/Versions/A/
|
|
* Frameworks/CarbonCore.framework/Versions/A/Headers/TextCommon.h
|
|
*/
|
|
{"MacRoman", kTextEncodingMacRoman},
|
|
{"MacJapanese", kTextEncodingMacJapanese},
|
|
{"MacChineseTrad", kTextEncodingMacChineseTrad},
|
|
{"MacKorean", kTextEncodingMacKorean},
|
|
{"MacArabic", kTextEncodingMacArabic},
|
|
{"MacHebrew", kTextEncodingMacHebrew},
|
|
{"MacGreek", kTextEncodingMacGreek},
|
|
{"MacCyrillic", kTextEncodingMacCyrillic},
|
|
{"MacDevanagari", kTextEncodingMacDevanagari},
|
|
{"MacGurmukhi", kTextEncodingMacGurmukhi},
|
|
{"MacGujarati", kTextEncodingMacGujarati},
|
|
{"MacOriya", kTextEncodingMacOriya},
|
|
{"MacBengali", kTextEncodingMacBengali},
|
|
{"MacTamil", kTextEncodingMacTamil},
|
|
{"MacTelugu", kTextEncodingMacTelugu},
|
|
{"MacKannada", kTextEncodingMacKannada},
|
|
{"MacMalayalam", kTextEncodingMacMalayalam},
|
|
{"MacSinhalese", kTextEncodingMacSinhalese},
|
|
{"MacBurmese", kTextEncodingMacBurmese},
|
|
{"MacKhmer", kTextEncodingMacKhmer},
|
|
{"MacThai", kTextEncodingMacThai},
|
|
{"MacLaotian", kTextEncodingMacLaotian},
|
|
{"MacGeorgian", kTextEncodingMacGeorgian},
|
|
{"MacArmenian", kTextEncodingMacArmenian},
|
|
{"MacChineseSimp", kTextEncodingMacChineseSimp},
|
|
{"MacTibetan", kTextEncodingMacTibetan},
|
|
{"MacMongolian", kTextEncodingMacMongolian},
|
|
{"MacEthiopic", kTextEncodingMacEthiopic},
|
|
{"MacCentralEurRoman", kTextEncodingMacCentralEurRoman},
|
|
{"MacVietnamese", kTextEncodingMacVietnamese},
|
|
{"MacExtArabic", kTextEncodingMacExtArabic},
|
|
{"MacSymbol", kTextEncodingMacSymbol},
|
|
{"MacDingbats", kTextEncodingMacDingbats},
|
|
{"MacTurkish", kTextEncodingMacTurkish},
|
|
{"MacCroatian", kTextEncodingMacCroatian},
|
|
{"MacIcelandic", kTextEncodingMacIcelandic},
|
|
{"MacRomanian", kTextEncodingMacRomanian},
|
|
{"MacCeltic", kTextEncodingMacCeltic},
|
|
{"MacGaelic", kTextEncodingMacGaelic},
|
|
{"MacKeyboardGlyphs", kTextEncodingMacKeyboardGlyphs},
|
|
{"MacTradChinese", kTextEncodingMacTradChinese},
|
|
{"MacRSymbol", kTextEncodingMacRSymbol},
|
|
{"MacSimpChinese", kTextEncodingMacSimpChinese},
|
|
{"MacGeez", kTextEncodingMacGeez},
|
|
{"MacEastEurRoman", kTextEncodingMacEastEurRoman},
|
|
{"MacUninterp", kTextEncodingMacUninterp},
|
|
{"MacUnicode", kTextEncodingMacUnicode},
|
|
{"MacFarsi", kTextEncodingMacFarsi},
|
|
{"MacUkrainian", kTextEncodingMacUkrainian},
|
|
{"MacInuit", kTextEncodingMacInuit},
|
|
{"MacVT100", kTextEncodingMacVT100},
|
|
{"MacHFS", kTextEncodingMacHFS},
|
|
{"UnicodeDefault", kTextEncodingUnicodeDefault},
|
|
{"UnicodeV1_1", kTextEncodingUnicodeV1_1},
|
|
{"ISO10646_1993", kTextEncodingISO10646_1993},
|
|
{"UnicodeV2_0", kTextEncodingUnicodeV2_0},
|
|
{"UnicodeV2_1", kTextEncodingUnicodeV2_1},
|
|
{"UnicodeV3_0", kTextEncodingUnicodeV3_0},
|
|
{"UnicodeV3_1", kTextEncodingUnicodeV3_1},
|
|
{"UnicodeV3_2", kTextEncodingUnicodeV3_2},
|
|
{"ISOLatin1", kTextEncodingISOLatin1},
|
|
{"ISOLatin2", kTextEncodingISOLatin2},
|
|
{"ISOLatin3", kTextEncodingISOLatin3},
|
|
{"ISOLatin4", kTextEncodingISOLatin4},
|
|
{"ISOLatinCyrillic", kTextEncodingISOLatinCyrillic},
|
|
{"ISOLatinArabic", kTextEncodingISOLatinArabic},
|
|
{"ISOLatinGreek", kTextEncodingISOLatinGreek},
|
|
{"ISOLatinHebrew", kTextEncodingISOLatinHebrew},
|
|
{"ISOLatin5", kTextEncodingISOLatin5},
|
|
{"ISOLatin6", kTextEncodingISOLatin6},
|
|
{"ISOLatin7", kTextEncodingISOLatin7},
|
|
{"ISOLatin8", kTextEncodingISOLatin8},
|
|
{"ISOLatin9", kTextEncodingISOLatin9},
|
|
{"DOSLatinUS", kTextEncodingDOSLatinUS},
|
|
{"DOSGreek", kTextEncodingDOSGreek},
|
|
{"DOSBalticRim", kTextEncodingDOSBalticRim},
|
|
{"DOSLatin1", kTextEncodingDOSLatin1},
|
|
{"DOSGreek1", kTextEncodingDOSGreek1},
|
|
{"DOSLatin2", kTextEncodingDOSLatin2},
|
|
{"DOSCyrillic", kTextEncodingDOSCyrillic},
|
|
{"DOSTurkish", kTextEncodingDOSTurkish},
|
|
{"DOSPortuguese", kTextEncodingDOSPortuguese},
|
|
{"DOSIcelandic", kTextEncodingDOSIcelandic},
|
|
{"DOSHebrew", kTextEncodingDOSHebrew},
|
|
{"DOSCanadianFrench", kTextEncodingDOSCanadianFrench},
|
|
{"DOSArabic", kTextEncodingDOSArabic},
|
|
{"DOSNordic", kTextEncodingDOSNordic},
|
|
{"DOSRussian", kTextEncodingDOSRussian},
|
|
{"DOSGreek2", kTextEncodingDOSGreek2},
|
|
{"DOSThai", kTextEncodingDOSThai},
|
|
{"DOSJapanese", kTextEncodingDOSJapanese},
|
|
{"DOSChineseSimplif", kTextEncodingDOSChineseSimplif},
|
|
{"DOSKorean", kTextEncodingDOSKorean},
|
|
{"DOSChineseTrad", kTextEncodingDOSChineseTrad},
|
|
{"WindowsLatin1", kTextEncodingWindowsLatin1},
|
|
{"WindowsANSI", kTextEncodingWindowsANSI},
|
|
{"WindowsLatin2", kTextEncodingWindowsLatin2},
|
|
{"WindowsCyrillic", kTextEncodingWindowsCyrillic},
|
|
{"WindowsGreek", kTextEncodingWindowsGreek},
|
|
{"WindowsLatin5", kTextEncodingWindowsLatin5},
|
|
{"WindowsHebrew", kTextEncodingWindowsHebrew},
|
|
{"WindowsArabic", kTextEncodingWindowsArabic},
|
|
{"WindowsBalticRim", kTextEncodingWindowsBalticRim},
|
|
{"WindowsVietnamese", kTextEncodingWindowsVietnamese},
|
|
{"WindowsKoreanJohab", kTextEncodingWindowsKoreanJohab},
|
|
{"US_ASCII", kTextEncodingUS_ASCII},
|
|
{"JIS_X0201_76", kTextEncodingJIS_X0201_76},
|
|
{"JIS_X0208_83", kTextEncodingJIS_X0208_83},
|
|
{"JIS_X0208_90", kTextEncodingJIS_X0208_90},
|
|
{"JIS_X0212_90", kTextEncodingJIS_X0212_90},
|
|
{"JIS_C6226_78", kTextEncodingJIS_C6226_78},
|
|
{"ShiftJIS_X0213_00", kTextEncodingShiftJIS_X0213_00},
|
|
{"GB_2312_80", kTextEncodingGB_2312_80},
|
|
{"GBK_95", kTextEncodingGBK_95},
|
|
{"GB_18030_2000", kTextEncodingGB_18030_2000},
|
|
{"KSC_5601_87", kTextEncodingKSC_5601_87},
|
|
{"KSC_5601_92_Johab", kTextEncodingKSC_5601_92_Johab},
|
|
{"CNS_11643_92_P1", kTextEncodingCNS_11643_92_P1},
|
|
{"CNS_11643_92_P2", kTextEncodingCNS_11643_92_P2},
|
|
{"CNS_11643_92_P3", kTextEncodingCNS_11643_92_P3},
|
|
{"ISO_2022_JP", kTextEncodingISO_2022_JP},
|
|
{"ISO_2022_JP_2", kTextEncodingISO_2022_JP_2},
|
|
{"ISO_2022_JP_1", kTextEncodingISO_2022_JP_1},
|
|
{"ISO_2022_JP_3", kTextEncodingISO_2022_JP_3},
|
|
{"ISO_2022_CN", kTextEncodingISO_2022_CN},
|
|
{"ISO_2022_CN_EXT", kTextEncodingISO_2022_CN_EXT},
|
|
{"ISO_2022_KR", kTextEncodingISO_2022_KR},
|
|
{"EUC_JP", kTextEncodingEUC_JP},
|
|
{"EUC_CN", kTextEncodingEUC_CN},
|
|
{"EUC_TW", kTextEncodingEUC_TW},
|
|
{"EUC_KR", kTextEncodingEUC_KR},
|
|
{"ShiftJIS", kTextEncodingShiftJIS},
|
|
{"KOI8_R", kTextEncodingKOI8_R},
|
|
{"Big5", kTextEncodingBig5},
|
|
{"MacRomanLatin1", kTextEncodingMacRomanLatin1},
|
|
{"HZ_GB_2312", kTextEncodingHZ_GB_2312},
|
|
{"Big5_HKSCS_1999", kTextEncodingBig5_HKSCS_1999},
|
|
{"NextStepLatin", kTextEncodingNextStepLatin},
|
|
{"EBCDIC_US", kTextEncodingEBCDIC_US},
|
|
{"EBCDIC_CP037", kTextEncodingEBCDIC_CP037},
|
|
{"MultiRun", kTextEncodingMultiRun},
|
|
|
|
/* Terminator */
|
|
{NULL, -1},
|
|
};
|
|
int i;
|
|
|
|
i = 0;
|
|
for (i = 0; encodetable[i].name != NULL; ++i)
|
|
{
|
|
if (STRICMP(encodename, encodetable[i].name) == 0)
|
|
break;
|
|
}
|
|
return encodetable[i].encode;
|
|
}
|
|
|
|
/*
|
|
* iconv interfaces
|
|
*/
|
|
|
|
iconv_t
|
|
iconv_open(const char* tocode, const char* fromcode)
|
|
{
|
|
TextEncoding toEnc, fromEnc;
|
|
iconv_t cd = NULL;
|
|
OSStatus st;
|
|
|
|
/* Verify to/from encoding name */
|
|
toEnc = get_textencoding(tocode);
|
|
fromEnc = get_textencoding(fromcode);
|
|
if (toEnc < 0 || fromEnc < 0)
|
|
goto ICONV_OPEN_ERR;
|
|
|
|
/* Allocate memory to object */
|
|
cd = (iconv_t)alloc(sizeof(struct _iconv_t));
|
|
if (!cd)
|
|
goto ICONV_OPEN_ERR;
|
|
memset(cd, 0, sizeof(struct _iconv_t));
|
|
|
|
/* Create converter */
|
|
if (fromEnc != toEnc)
|
|
{
|
|
TRACE("*** fromEnc=%d toEnc=%d\n", (int)fromEnc, (int)toEnc);
|
|
st = TECCreateConverter(&cd->tec, fromEnc, toEnc);
|
|
if (st != 0)
|
|
{
|
|
TRACE("*** TECCreateConverter()=%d\n", (int)st);
|
|
goto ICONV_OPEN_ERR;
|
|
}
|
|
/* Create reverse converter */
|
|
st = TECCreateConverter(&cd->tecReverse, toEnc, fromEnc);
|
|
if (st != 0)
|
|
{
|
|
TRACE("*** TECCreateConverter()=%d (reverse)\n", (int)st);
|
|
goto ICONV_OPEN_ERR;
|
|
}
|
|
/* Create Sniffer */
|
|
st = TECCreateSniffer(&cd->sniff, &fromEnc, 1);
|
|
if (st != 0)
|
|
{
|
|
TRACE("*** TECCreateSniffer()=%d\n", (int)st);
|
|
goto ICONV_OPEN_ERR;
|
|
}
|
|
}
|
|
|
|
cd->from = fromEnc;
|
|
cd->to = toEnc;
|
|
last_errno = 0;
|
|
return cd;
|
|
|
|
ICONV_OPEN_ERR:
|
|
if (cd)
|
|
iconv_close(cd);
|
|
last_errno = EINVAL;
|
|
return (iconv_t)-1;
|
|
}
|
|
|
|
/*
|
|
* Used when there are same value in 'from encoding' and 'to encoding'.
|
|
* TEC doesn't support conversion between same encodings, and
|
|
* TECCreateConverter() failed.
|
|
*/
|
|
static size_t
|
|
null_conv(iconv_t cd, const char **inbuf, size_t *inbytesleft,
|
|
char **outbuf, size_t *outbytesleft)
|
|
{
|
|
const char* buf_in = inbuf && *inbuf ? *inbuf : NULL;
|
|
char* buf_out = outbuf && *outbuf ? *outbuf : NULL;
|
|
|
|
if (buf_in)
|
|
{
|
|
int in_len = inbytesleft ? *inbytesleft : 0;
|
|
int out_len = outbytesleft ? *outbytesleft : 0;
|
|
|
|
if (!buf_out || out_len <= 0)
|
|
{
|
|
last_errno = E2BIG;
|
|
return -1;
|
|
}
|
|
else if (in_len > 0)
|
|
{
|
|
int len = in_len < out_len ? in_len : out_len;
|
|
|
|
memcpy (buf_out, buf_in, len);
|
|
*inbuf += len;
|
|
*outbuf += len;
|
|
*inbytesleft -= len;
|
|
*outbytesleft -= len;
|
|
if (*outbytesleft <= 0)
|
|
{
|
|
last_errno = E2BIG;
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
last_errno = 0;
|
|
return 0;
|
|
}
|
|
|
|
size_t
|
|
iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft,
|
|
char **outbuf, size_t *outbytesleft)
|
|
{
|
|
ConstTextPtr buf_in;
|
|
TextPtr buf_out;
|
|
ByteCount out_len, out_true;
|
|
ByteCount in_len, in_true;
|
|
OSStatus st;
|
|
|
|
if (!cd)
|
|
{
|
|
last_errno = ENOENT; /* TODO: Another error code should be set */
|
|
return -1;
|
|
}
|
|
if (cd->from == cd->to)
|
|
return null_conv(cd, inbuf, inbytesleft, outbuf, outbytesleft) ;
|
|
|
|
buf_in = (TextPtr) inbuf ;
|
|
buf_out = (TextPtr) outbuf ;
|
|
out_len = out_true = -1;
|
|
in_len = in_true = -1;
|
|
|
|
if (buf_in && buf_out)
|
|
{
|
|
ItemCount error, feature;
|
|
|
|
/* Normal convert mode */
|
|
if (!inbytesleft || !outbytesleft)
|
|
{
|
|
last_errno = EFAULT;
|
|
return -1;
|
|
}
|
|
in_len = *inbytesleft;
|
|
out_len = *outbytesleft;
|
|
|
|
/* Check stream is form in expected encoding or not */
|
|
st = TECSniffTextEncoding(cd->sniff, (TextPtr)buf_in, in_len,
|
|
&cd->from, 1, &error, 1, &feature, 1);
|
|
TRACE("TECSniffTextEncoding()=%d error=%d feature=%d\n",
|
|
(int)st, (int)error, (int)feature);
|
|
if ((error != 0 || feature == 0)
|
|
&& !(error == 0xffffffff && feature == 0xffffffff))
|
|
/* Not expected encoding */
|
|
st = kTECUnmappableElementErr;
|
|
else
|
|
{
|
|
/* Do convert */
|
|
st = TECConvertText(cd->tec,
|
|
buf_in, in_len, &in_true,
|
|
buf_out, out_len, &out_true);
|
|
/* Verify converted text. Compare original text with reverse
|
|
* converted text. If not match, there is some problem on
|
|
* converting. */
|
|
if (st == 0 && in_true > 0)
|
|
{
|
|
ByteCount rev_in, rev_out;
|
|
TextPtr buf_rev = (TextPtr)alloc(in_true);
|
|
|
|
if (buf_rev)
|
|
{
|
|
st = TECConvertText(cd->tecReverse,
|
|
buf_out, out_true, &rev_in,
|
|
buf_rev, in_true, &rev_out);
|
|
if (st != 0 || rev_in != out_true || rev_out != in_true
|
|
|| memcmp(buf_rev, buf_in, rev_out) != 0)
|
|
{
|
|
#ifdef ICONVOSX_DEBUG
|
|
fprintf(stderr, " reverse conversion failed.\n");
|
|
#endif
|
|
st = kTECUnmappableElementErr;
|
|
}
|
|
vim_free(buf_rev);
|
|
}
|
|
else
|
|
st = kTECUnmappableElementErr;
|
|
}
|
|
}
|
|
}
|
|
else if (!buf_in && buf_out)
|
|
{
|
|
/* Flush all buffered strings to buffer, and reset status */
|
|
if (!outbytesleft)
|
|
{
|
|
last_errno = EFAULT;
|
|
return -1;
|
|
}
|
|
out_len = *outbytesleft;
|
|
st = TECFlushText(cd->tec,
|
|
buf_out, out_len, &out_true);
|
|
}
|
|
else if (!buf_in && !buf_out)
|
|
{
|
|
/* Reset cd's status and cancel buffered strings */
|
|
unsigned char tmp_out[256];
|
|
|
|
buf_out = tmp_out;
|
|
out_len = sizeof(tmp_out);
|
|
st = TECFlushText(cd->tec,
|
|
buf_out, out_len, &out_true);
|
|
}
|
|
else
|
|
{
|
|
last_errno = EFAULT;
|
|
return -1;
|
|
}
|
|
TRACE("st=%d, buf_in=%p, in_len=%d, in_true=%d\n"
|
|
" buf_out=%p, out_len=%d, out_true=%d\n", (int)st,
|
|
buf_in, (int)in_len, (int)in_true,
|
|
buf_out, (int)out_len, (int)out_true);
|
|
|
|
switch (st)
|
|
{
|
|
case 0:
|
|
/* No error */
|
|
if (inbytesleft)
|
|
*inbytesleft -= in_true;
|
|
if (outbytesleft)
|
|
*outbytesleft -= out_true;
|
|
if (inbuf && *inbuf)
|
|
*inbuf += in_true;
|
|
if (outbuf && *outbuf)
|
|
*outbuf += out_true;
|
|
last_errno = 0;
|
|
return 0; /* No error */
|
|
case kTECUnmappableElementErr:
|
|
last_errno = EILSEQ;
|
|
case kTECIncompleteElementErr:
|
|
last_errno = EINVAL;
|
|
case kTECOutputBufferFullStatus:
|
|
last_errno = E2BIG;
|
|
return -1;
|
|
default:
|
|
TRACE("iconv(%p, %p, %p, %p, %p) failed. (%d)\n",
|
|
cd, inbuf, inbytesleft, outbuf, outbytesleft, (int)st);
|
|
last_errno = EFAULT;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int
|
|
iconv_close(iconv_t cd)
|
|
{
|
|
if (cd)
|
|
{
|
|
/* Free all elements of iconv_t */
|
|
if (cd->tec)
|
|
TECDisposeConverter(cd->tec);
|
|
if (cd->tecReverse)
|
|
TECDisposeConverter(cd->tecReverse);
|
|
if (cd->sniff)
|
|
TECDisposeSniffer(cd->sniff);
|
|
vim_free(cd);
|
|
last_errno = 0;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
last_errno = EINVAL;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int *
|
|
iconv_errno()
|
|
{
|
|
return &last_errno;
|
|
}
|
|
#endif /* MACOS_X_ICONVEMU */
|
|
|
|
#ifdef USE_MCH_GETTEXT
|
|
|
|
#define GETTEXT_BUFNUM 64
|
|
#define GETTEXT_BUFSIZE 256
|
|
|
|
char *
|
|
mch_gettext(const char *msgid)
|
|
{
|
|
static char buf[GETTEXT_BUFNUM][GETTEXT_BUFSIZE];
|
|
static int bufnum = 0;
|
|
const char *msg = NULL;
|
|
CFStringRef strkey = NULL, strmsg = NULL;
|
|
CFStringEncoding enc;
|
|
|
|
if (!msgid)
|
|
goto MCH_GETTEXT_FINISH;
|
|
enc = CFStringGetSystemEncoding();
|
|
TRACE("mch_gettext(%s)\n", msgid);
|
|
|
|
strkey = CFStringCreateWithCString(NULL, msgid, enc);
|
|
if (!strkey)
|
|
{
|
|
TRACE(" Can't create a CFString for msgid.\n");
|
|
goto MCH_GETTEXT_FINISH;
|
|
}
|
|
|
|
strmsg = CFCopyLocalizedString(strkey, NULL);
|
|
if (!strmsg)
|
|
{
|
|
TRACE(" No localized strings for msgid.\n");
|
|
goto MCH_GETTEXT_FINISH;
|
|
}
|
|
|
|
msg = CFStringGetCStringPtr(strmsg, enc);
|
|
if (!msg)
|
|
{
|
|
/* This is as backup when CFStringGetCStringPtr was failed */
|
|
CFStringGetCString(strmsg, buf[bufnum], GETTEXT_BUFSIZE, enc);
|
|
msg = buf[bufnum];
|
|
if (++bufnum >= GETTEXT_BUFNUM)
|
|
bufnum = 0;
|
|
}
|
|
TRACE(" Localized to: %s\n", msg);
|
|
|
|
MCH_GETTEXT_FINISH:
|
|
if (strkey)
|
|
CFRelease(strkey);
|
|
if (strmsg)
|
|
CFRelease(strmsg);
|
|
return (char *)(msg ? msg : msgid);
|
|
}
|
|
|
|
char *
|
|
mch_bindtextdomain(const char *domain, const char *dirname)
|
|
{
|
|
TRACE("mch_bindtextdomain(%s, %s)\n", domain, dirname);
|
|
return (char*)dirname;
|
|
}
|
|
|
|
char *
|
|
mch_textdomain(const char *domain)
|
|
{
|
|
TRACE("mch_textdomain(%s)\n", domain);
|
|
return (char*)domain;
|
|
}
|
|
#endif
|