1 /* vi:set ts=8 sts=4 sw=4:
3 * VIM - Vi IMproved by Bram Moolenaar
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
11 * os_macosx.c -- Mac specific things for Mac OS/X.
15 # ifdef HAVE_CONFIG_H /* Using Makefile. */
18 # include "os_unix.c" /* Using Project Builder */
21 Error
: MACOS
9 is no longer supported in Vim
7
32 /* vsnprintf(buf, sizeof(buf), fmt, args);*/
33 fprintf(stderr
, "%s", buf
);
38 #ifdef MACOS_X_ICONVEMU
40 * Libiconv emulation layer
46 TECObjectRef tecReverse
;
47 TECSnifferObjectRef sniff
;
51 /* typedef struct _iconv_t *iconv_t; */
54 static int last_errno
= 0;
57 * Get TextEncoding from iconv's encoding name
60 get_textencoding(const char* encodename
)
66 /* ISO-8859 encodings family */
67 {"latin1", kTextEncodingISOLatin1
},
68 {"latin2", kTextEncodingISOLatin2
},
69 {"latin3", kTextEncodingISOLatin3
},
70 {"latin4", kTextEncodingISOLatin4
},
71 {"latin5", kTextEncodingISOLatin5
},
72 {"latin6", kTextEncodingISOLatin6
},
73 {"latin7", kTextEncodingISOLatin7
},
74 {"latin8", kTextEncodingISOLatin8
},
75 {"latin9", kTextEncodingISOLatin9
},
76 {"iso-8859-1", kTextEncodingISOLatin1
},
77 {"iso-8859-2", kTextEncodingISOLatin2
},
78 {"iso-8859-3", kTextEncodingISOLatin3
},
79 {"iso-8859-4", kTextEncodingISOLatin4
},
80 {"iso-8859-5", kTextEncodingISOLatinCyrillic
},
81 {"iso-8859-6", kTextEncodingISOLatinArabic
},
82 {"iso-8859-7", kTextEncodingISOLatinGreek
},
83 {"iso-8859-8", kTextEncodingISOLatinHebrew
},
84 {"iso-8859-9", kTextEncodingISOLatin5
},
85 {"iso-8859-10", kTextEncodingISOLatin6
},
86 {"iso-8859-15", kTextEncodingISOLatin9
},
88 /* Unicode encodings. */
89 /* TODO: Add other type of unicode */
90 {"ucs-2", kTextEncodingMacUnicode
},
92 /* Japanese encoding aliases */
93 {"cp932", kTextEncodingShiftJIS
},
94 {"shift-jis", kTextEncodingShiftJIS
},
95 {"euc-jp", kTextEncodingEUC_JP
},
96 {"iso-2022-jp", kTextEncodingISO_2022_JP
},
97 {"iso-2022-jp-1", kTextEncodingISO_2022_JP_1
},
98 {"iso-2022-jp-2", kTextEncodingISO_2022_JP_2
},
99 {"iso-2022-jp-3", kTextEncodingISO_2022_JP_3
},
101 /* Other aliases. These aliases in this block are just guessed. */
102 /* TODO: Must be verified. */
103 {"gb2312", kTextEncodingGB_2312_80
},
104 {"cp936", kTextEncodingMacChineseSimp
},
105 {"euc-cn", kTextEncodingEUC_CN
},
106 {"cp950", kTextEncodingMacChineseTrad
},
107 {"euc-tw", kTextEncodingEUC_TW
},
108 {"cp949", kTextEncodingMacKorean
},
109 {"euc-kr", kTextEncodingEUC_KR
},
112 * All encodings supported by Macintosh. You can find these values
114 * /System/Library/Frameworks/CoreServices.framework/Versions/A/
115 * Frameworks/CarbonCore.framework/Versions/A/Headers/TextCommon.h
117 {"MacRoman", kTextEncodingMacRoman
},
118 {"MacJapanese", kTextEncodingMacJapanese
},
119 {"MacChineseTrad", kTextEncodingMacChineseTrad
},
120 {"MacKorean", kTextEncodingMacKorean
},
121 {"MacArabic", kTextEncodingMacArabic
},
122 {"MacHebrew", kTextEncodingMacHebrew
},
123 {"MacGreek", kTextEncodingMacGreek
},
124 {"MacCyrillic", kTextEncodingMacCyrillic
},
125 {"MacDevanagari", kTextEncodingMacDevanagari
},
126 {"MacGurmukhi", kTextEncodingMacGurmukhi
},
127 {"MacGujarati", kTextEncodingMacGujarati
},
128 {"MacOriya", kTextEncodingMacOriya
},
129 {"MacBengali", kTextEncodingMacBengali
},
130 {"MacTamil", kTextEncodingMacTamil
},
131 {"MacTelugu", kTextEncodingMacTelugu
},
132 {"MacKannada", kTextEncodingMacKannada
},
133 {"MacMalayalam", kTextEncodingMacMalayalam
},
134 {"MacSinhalese", kTextEncodingMacSinhalese
},
135 {"MacBurmese", kTextEncodingMacBurmese
},
136 {"MacKhmer", kTextEncodingMacKhmer
},
137 {"MacThai", kTextEncodingMacThai
},
138 {"MacLaotian", kTextEncodingMacLaotian
},
139 {"MacGeorgian", kTextEncodingMacGeorgian
},
140 {"MacArmenian", kTextEncodingMacArmenian
},
141 {"MacChineseSimp", kTextEncodingMacChineseSimp
},
142 {"MacTibetan", kTextEncodingMacTibetan
},
143 {"MacMongolian", kTextEncodingMacMongolian
},
144 {"MacEthiopic", kTextEncodingMacEthiopic
},
145 {"MacCentralEurRoman", kTextEncodingMacCentralEurRoman
},
146 {"MacVietnamese", kTextEncodingMacVietnamese
},
147 {"MacExtArabic", kTextEncodingMacExtArabic
},
148 {"MacSymbol", kTextEncodingMacSymbol
},
149 {"MacDingbats", kTextEncodingMacDingbats
},
150 {"MacTurkish", kTextEncodingMacTurkish
},
151 {"MacCroatian", kTextEncodingMacCroatian
},
152 {"MacIcelandic", kTextEncodingMacIcelandic
},
153 {"MacRomanian", kTextEncodingMacRomanian
},
154 {"MacCeltic", kTextEncodingMacCeltic
},
155 {"MacGaelic", kTextEncodingMacGaelic
},
156 {"MacKeyboardGlyphs", kTextEncodingMacKeyboardGlyphs
},
157 {"MacTradChinese", kTextEncodingMacTradChinese
},
158 {"MacRSymbol", kTextEncodingMacRSymbol
},
159 {"MacSimpChinese", kTextEncodingMacSimpChinese
},
160 {"MacGeez", kTextEncodingMacGeez
},
161 {"MacEastEurRoman", kTextEncodingMacEastEurRoman
},
162 {"MacUninterp", kTextEncodingMacUninterp
},
163 {"MacUnicode", kTextEncodingMacUnicode
},
164 {"MacFarsi", kTextEncodingMacFarsi
},
165 {"MacUkrainian", kTextEncodingMacUkrainian
},
166 {"MacInuit", kTextEncodingMacInuit
},
167 {"MacVT100", kTextEncodingMacVT100
},
168 {"MacHFS", kTextEncodingMacHFS
},
169 {"UnicodeDefault", kTextEncodingUnicodeDefault
},
170 {"UnicodeV1_1", kTextEncodingUnicodeV1_1
},
171 {"ISO10646_1993", kTextEncodingISO10646_1993
},
172 {"UnicodeV2_0", kTextEncodingUnicodeV2_0
},
173 {"UnicodeV2_1", kTextEncodingUnicodeV2_1
},
174 {"UnicodeV3_0", kTextEncodingUnicodeV3_0
},
175 {"UnicodeV3_1", kTextEncodingUnicodeV3_1
},
176 {"UnicodeV3_2", kTextEncodingUnicodeV3_2
},
177 {"ISOLatin1", kTextEncodingISOLatin1
},
178 {"ISOLatin2", kTextEncodingISOLatin2
},
179 {"ISOLatin3", kTextEncodingISOLatin3
},
180 {"ISOLatin4", kTextEncodingISOLatin4
},
181 {"ISOLatinCyrillic", kTextEncodingISOLatinCyrillic
},
182 {"ISOLatinArabic", kTextEncodingISOLatinArabic
},
183 {"ISOLatinGreek", kTextEncodingISOLatinGreek
},
184 {"ISOLatinHebrew", kTextEncodingISOLatinHebrew
},
185 {"ISOLatin5", kTextEncodingISOLatin5
},
186 {"ISOLatin6", kTextEncodingISOLatin6
},
187 {"ISOLatin7", kTextEncodingISOLatin7
},
188 {"ISOLatin8", kTextEncodingISOLatin8
},
189 {"ISOLatin9", kTextEncodingISOLatin9
},
190 {"DOSLatinUS", kTextEncodingDOSLatinUS
},
191 {"DOSGreek", kTextEncodingDOSGreek
},
192 {"DOSBalticRim", kTextEncodingDOSBalticRim
},
193 {"DOSLatin1", kTextEncodingDOSLatin1
},
194 {"DOSGreek1", kTextEncodingDOSGreek1
},
195 {"DOSLatin2", kTextEncodingDOSLatin2
},
196 {"DOSCyrillic", kTextEncodingDOSCyrillic
},
197 {"DOSTurkish", kTextEncodingDOSTurkish
},
198 {"DOSPortuguese", kTextEncodingDOSPortuguese
},
199 {"DOSIcelandic", kTextEncodingDOSIcelandic
},
200 {"DOSHebrew", kTextEncodingDOSHebrew
},
201 {"DOSCanadianFrench", kTextEncodingDOSCanadianFrench
},
202 {"DOSArabic", kTextEncodingDOSArabic
},
203 {"DOSNordic", kTextEncodingDOSNordic
},
204 {"DOSRussian", kTextEncodingDOSRussian
},
205 {"DOSGreek2", kTextEncodingDOSGreek2
},
206 {"DOSThai", kTextEncodingDOSThai
},
207 {"DOSJapanese", kTextEncodingDOSJapanese
},
208 {"DOSChineseSimplif", kTextEncodingDOSChineseSimplif
},
209 {"DOSKorean", kTextEncodingDOSKorean
},
210 {"DOSChineseTrad", kTextEncodingDOSChineseTrad
},
211 {"WindowsLatin1", kTextEncodingWindowsLatin1
},
212 {"WindowsANSI", kTextEncodingWindowsANSI
},
213 {"WindowsLatin2", kTextEncodingWindowsLatin2
},
214 {"WindowsCyrillic", kTextEncodingWindowsCyrillic
},
215 {"WindowsGreek", kTextEncodingWindowsGreek
},
216 {"WindowsLatin5", kTextEncodingWindowsLatin5
},
217 {"WindowsHebrew", kTextEncodingWindowsHebrew
},
218 {"WindowsArabic", kTextEncodingWindowsArabic
},
219 {"WindowsBalticRim", kTextEncodingWindowsBalticRim
},
220 {"WindowsVietnamese", kTextEncodingWindowsVietnamese
},
221 {"WindowsKoreanJohab", kTextEncodingWindowsKoreanJohab
},
222 {"US_ASCII", kTextEncodingUS_ASCII
},
223 {"JIS_X0201_76", kTextEncodingJIS_X0201_76
},
224 {"JIS_X0208_83", kTextEncodingJIS_X0208_83
},
225 {"JIS_X0208_90", kTextEncodingJIS_X0208_90
},
226 {"JIS_X0212_90", kTextEncodingJIS_X0212_90
},
227 {"JIS_C6226_78", kTextEncodingJIS_C6226_78
},
228 {"ShiftJIS_X0213_00", kTextEncodingShiftJIS_X0213_00
},
229 {"GB_2312_80", kTextEncodingGB_2312_80
},
230 {"GBK_95", kTextEncodingGBK_95
},
231 {"GB_18030_2000", kTextEncodingGB_18030_2000
},
232 {"KSC_5601_87", kTextEncodingKSC_5601_87
},
233 {"KSC_5601_92_Johab", kTextEncodingKSC_5601_92_Johab
},
234 {"CNS_11643_92_P1", kTextEncodingCNS_11643_92_P1
},
235 {"CNS_11643_92_P2", kTextEncodingCNS_11643_92_P2
},
236 {"CNS_11643_92_P3", kTextEncodingCNS_11643_92_P3
},
237 {"ISO_2022_JP", kTextEncodingISO_2022_JP
},
238 {"ISO_2022_JP_2", kTextEncodingISO_2022_JP_2
},
239 {"ISO_2022_JP_1", kTextEncodingISO_2022_JP_1
},
240 {"ISO_2022_JP_3", kTextEncodingISO_2022_JP_3
},
241 {"ISO_2022_CN", kTextEncodingISO_2022_CN
},
242 {"ISO_2022_CN_EXT", kTextEncodingISO_2022_CN_EXT
},
243 {"ISO_2022_KR", kTextEncodingISO_2022_KR
},
244 {"EUC_JP", kTextEncodingEUC_JP
},
245 {"EUC_CN", kTextEncodingEUC_CN
},
246 {"EUC_TW", kTextEncodingEUC_TW
},
247 {"EUC_KR", kTextEncodingEUC_KR
},
248 {"ShiftJIS", kTextEncodingShiftJIS
},
249 {"KOI8_R", kTextEncodingKOI8_R
},
250 {"Big5", kTextEncodingBig5
},
251 {"MacRomanLatin1", kTextEncodingMacRomanLatin1
},
252 {"HZ_GB_2312", kTextEncodingHZ_GB_2312
},
253 {"Big5_HKSCS_1999", kTextEncodingBig5_HKSCS_1999
},
254 {"NextStepLatin", kTextEncodingNextStepLatin
},
255 {"EBCDIC_US", kTextEncodingEBCDIC_US
},
256 {"EBCDIC_CP037", kTextEncodingEBCDIC_CP037
},
257 {"MultiRun", kTextEncodingMultiRun
},
265 for (i
= 0; encodetable
[i
].name
!= NULL
; ++i
)
267 if (STRICMP(encodename
, encodetable
[i
].name
) == 0)
270 return encodetable
[i
].encode
;
278 iconv_open(const char* tocode
, const char* fromcode
)
280 TextEncoding toEnc
, fromEnc
;
284 /* Verify to/from encoding name */
285 toEnc
= get_textencoding(tocode
);
286 fromEnc
= get_textencoding(fromcode
);
287 if (toEnc
< 0 || fromEnc
< 0)
290 /* Allocate memory to object */
291 cd
= (iconv_t
)alloc(sizeof(struct _iconv_t
));
294 memset(cd
, 0, sizeof(struct _iconv_t
));
296 /* Create converter */
297 if (fromEnc
!= toEnc
)
299 TRACE("*** fromEnc=%d toEnc=%d\n", (int)fromEnc
, (int)toEnc
);
300 st
= TECCreateConverter(&cd
->tec
, fromEnc
, toEnc
);
303 TRACE("*** TECCreateConverter()=%d\n", (int)st
);
306 /* Create reverse converter */
307 st
= TECCreateConverter(&cd
->tecReverse
, toEnc
, fromEnc
);
310 TRACE("*** TECCreateConverter()=%d (reverse)\n", (int)st
);
314 st
= TECCreateSniffer(&cd
->sniff
, &fromEnc
, 1);
317 TRACE("*** TECCreateSniffer()=%d\n", (int)st
);
335 * Used when there are same value in 'from encoding' and 'to encoding'.
336 * TEC doesn't support conversion between same encodings, and
337 * TECCreateConverter() failed.
340 null_conv(iconv_t cd
, const char **inbuf
, size_t *inbytesleft
,
341 char **outbuf
, size_t *outbytesleft
)
343 const char* buf_in
= inbuf
&& *inbuf
? *inbuf
: NULL
;
344 char* buf_out
= outbuf
&& *outbuf
? *outbuf
: NULL
;
348 int in_len
= inbytesleft
? *inbytesleft
: 0;
349 int out_len
= outbytesleft
? *outbytesleft
: 0;
351 if (!buf_out
|| out_len
<= 0)
358 int len
= in_len
< out_len
? in_len
: out_len
;
360 memcpy (buf_out
, buf_in
, len
);
364 *outbytesleft
-= len
;
365 if (*outbytesleft
<= 0)
377 iconv(iconv_t cd
, const char **inbuf
, size_t *inbytesleft
,
378 char **outbuf
, size_t *outbytesleft
)
382 ByteCount out_len
, out_true
;
383 ByteCount in_len
, in_true
;
388 last_errno
= ENOENT
; /* TODO: Another error code should be set */
391 if (cd
->from
== cd
->to
)
392 return null_conv(cd
, inbuf
, inbytesleft
, outbuf
, outbytesleft
) ;
394 buf_in
= (TextPtr
) inbuf
;
395 buf_out
= (TextPtr
) outbuf
;
396 out_len
= out_true
= -1;
397 in_len
= in_true
= -1;
399 if (buf_in
&& buf_out
)
401 ItemCount error
, feature
;
403 /* Normal convert mode */
404 if (!inbytesleft
|| !outbytesleft
)
409 in_len
= *inbytesleft
;
410 out_len
= *outbytesleft
;
412 /* Check stream is form in expected encoding or not */
413 st
= TECSniffTextEncoding(cd
->sniff
, (TextPtr
)buf_in
, in_len
,
414 &cd
->from
, 1, &error
, 1, &feature
, 1);
415 TRACE("TECSniffTextEncoding()=%d error=%d feature=%d\n",
416 (int)st
, (int)error
, (int)feature
);
417 if ((error
!= 0 || feature
== 0)
418 && !(error
== 0xffffffff && feature
== 0xffffffff))
419 /* Not expected encoding */
420 st
= kTECUnmappableElementErr
;
424 st
= TECConvertText(cd
->tec
,
425 buf_in
, in_len
, &in_true
,
426 buf_out
, out_len
, &out_true
);
427 /* Verify converted text. Compare original text with reverse
428 * converted text. If not match, there is some problem on
430 if (st
== 0 && in_true
> 0)
432 ByteCount rev_in
, rev_out
;
433 TextPtr buf_rev
= (TextPtr
)alloc(in_true
);
437 st
= TECConvertText(cd
->tecReverse
,
438 buf_out
, out_true
, &rev_in
,
439 buf_rev
, in_true
, &rev_out
);
440 if (st
!= 0 || rev_in
!= out_true
|| rev_out
!= in_true
441 || memcmp(buf_rev
, buf_in
, rev_out
) != 0)
443 #ifdef ICONVOSX_DEBUG
444 fprintf(stderr
, " reverse conversion failed.\n");
446 st
= kTECUnmappableElementErr
;
451 st
= kTECUnmappableElementErr
;
455 else if (!buf_in
&& buf_out
)
457 /* Flush all buffered strings to buffer, and reset status */
463 out_len
= *outbytesleft
;
464 st
= TECFlushText(cd
->tec
,
465 buf_out
, out_len
, &out_true
);
467 else if (!buf_in
&& !buf_out
)
469 /* Reset cd's status and cancel buffered strings */
470 unsigned char tmp_out
[256];
473 out_len
= sizeof(tmp_out
);
474 st
= TECFlushText(cd
->tec
,
475 buf_out
, out_len
, &out_true
);
482 TRACE("st=%d, buf_in=%p, in_len=%d, in_true=%d\n"
483 " buf_out=%p, out_len=%d, out_true=%d\n", (int)st
,
484 buf_in
, (int)in_len
, (int)in_true
,
485 buf_out
, (int)out_len
, (int)out_true
);
492 *inbytesleft
-= in_true
;
494 *outbytesleft
-= out_true
;
497 if (outbuf
&& *outbuf
)
500 return 0; /* No error */
501 case kTECUnmappableElementErr
:
503 case kTECIncompleteElementErr
:
505 case kTECOutputBufferFullStatus
:
509 TRACE("iconv(%p, %p, %p, %p, %p) failed. (%d)\n",
510 cd
, inbuf
, inbytesleft
, outbuf
, outbytesleft
, (int)st
);
517 iconv_close(iconv_t cd
)
521 /* Free all elements of iconv_t */
523 TECDisposeConverter(cd
->tec
);
525 TECDisposeConverter(cd
->tecReverse
);
527 TECDisposeSniffer(cd
->sniff
);
544 #endif /* MACOS_X_ICONVEMU */
546 #ifdef USE_MCH_GETTEXT
548 #define GETTEXT_BUFNUM 64
549 #define GETTEXT_BUFSIZE 256
552 mch_gettext(const char *msgid
)
554 static char buf
[GETTEXT_BUFNUM
][GETTEXT_BUFSIZE
];
555 static int bufnum
= 0;
556 const char *msg
= NULL
;
557 CFStringRef strkey
= NULL
, strmsg
= NULL
;
558 CFStringEncoding enc
;
561 goto MCH_GETTEXT_FINISH
;
562 enc
= CFStringGetSystemEncoding();
563 TRACE("mch_gettext(%s)\n", msgid
);
565 strkey
= CFStringCreateWithCString(NULL
, msgid
, enc
);
568 TRACE(" Can't create a CFString for msgid.\n");
569 goto MCH_GETTEXT_FINISH
;
572 strmsg
= CFCopyLocalizedString(strkey
, NULL
);
575 TRACE(" No localized strings for msgid.\n");
576 goto MCH_GETTEXT_FINISH
;
579 msg
= CFStringGetCStringPtr(strmsg
, enc
);
582 /* This is as backup when CFStringGetCStringPtr was failed */
583 CFStringGetCString(strmsg
, buf
[bufnum
], GETTEXT_BUFSIZE
, enc
);
585 if (++bufnum
>= GETTEXT_BUFNUM
)
588 TRACE(" Localized to: %s\n", msg
);
595 return (char *)(msg
? msg
: msgid
);
599 mch_bindtextdomain(const char *domain
, const char *dirname
)
601 TRACE("mch_bindtextdomain(%s, %s)\n", domain
, dirname
);
602 return (char*)dirname
;
606 mch_textdomain(const char *domain
)
608 TRACE("mch_textdomain(%s)\n", domain
);
609 return (char*)domain
;
621 * On OS X, you have to exec after a fork, otherwise calls to frameworks
622 * will assert (and without Core Foundation, you can't start the gui. What
623 * fun.). See CAVEATS at:
625 * http://developer.apple.com/documentation/Darwin/Reference/ManPages/
628 * Since we have to go through this anyways, we might as well use vfork.
629 * But: then we can't detach from our starting shell, so stick with fork.
632 /* Stolen from http://paste.lisp.org/display/50906 */
633 extern int *_NSGetArgc(void);
634 extern char ***_NSGetArgv(void);
636 int argc
= *_NSGetArgc();
637 char ** argv
= *_NSGetArgv();
638 char * newargv
[argc
+2];
640 newargv
[0] = argv
[0];
643 * Make sure "-f" is in front of potential "--remote" flags, else
644 * they would consume it.
648 for (i
= 1; i
< argc
; i
++) {
649 newargv
[i
+ 1] = argv
[i
];
651 newargv
[argc
+1] = NULL
;
657 fprintf(stderr
, "vim: Mac OS X workaround fork() failed!");
663 /* Make sure we survive our shell */
666 /* Restarts the vim process, will not return. */
667 execvp(argv
[0], newargv
);
669 /* If we come here, exec has failed. bail. */