forked from ruby/ruby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
localeinit.c
137 lines (124 loc) · 3.04 KB
/
localeinit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**********************************************************************
localeinit.c -
$Author$
created at: Thu Jul 11 22:09:57 JST 2013
Copyright (C) 2013 Yukihiro Matsumoto
**********************************************************************/
#include "ruby/encoding.h"
#include "internal.h"
#include "encindex.h"
#ifdef __CYGWIN__
#include <windows.h>
#endif
#ifdef HAVE_LANGINFO_H
#include <langinfo.h>
#endif
#if defined _WIN32 || defined __CYGWIN__
#define SIZEOF_CP_NAME ((sizeof(UINT) * 8 / 3) + 4)
#define CP_FORMAT(buf, codepage) snprintf(buf, sizeof(buf), "CP%u", (codepage))
extern UINT ruby_w32_codepage[2];
#endif
#ifndef NO_LOCALE_CHARMAP
# if defined _WIN32 || defined __CYGWIN__ || defined HAVE_LANGINFO_H
# define NO_LOCALE_CHARMAP 0
# else
# define NO_LOCALE_CHARMAP 1
# endif
#endif
#if !NO_LOCALE_CHARMAP
static VALUE
locale_charmap(VALUE (*conv)(const char *))
{
const char *codeset = 0;
#if defined _WIN32 || defined __CYGWIN__
char cp[SIZEOF_CP_NAME];
# ifdef __CYGWIN__
const char *nl_langinfo_codeset(void);
codeset = nl_langinfo_codeset();
# endif
if (!codeset) {
UINT codepage = ruby_w32_codepage[0];
if (!codepage) codepage = GetConsoleCP();
if (!codepage) codepage = GetACP();
CP_FORMAT(cp, codepage);
codeset = cp;
}
#elif defined HAVE_LANGINFO_H
codeset = nl_langinfo(CODESET);
ASSUME(codeset);
#else
# error locale_charmap() is not implemented
#endif
return (*conv)(codeset);
}
#endif
/*
* call-seq:
* Encoding.locale_charmap -> string
*
* Returns the locale charmap name.
* It returns nil if no appropriate information.
*
* Debian GNU/Linux
* LANG=C
* Encoding.locale_charmap #=> "ANSI_X3.4-1968"
* LANG=ja_JP.EUC-JP
* Encoding.locale_charmap #=> "EUC-JP"
*
* SunOS 5
* LANG=C
* Encoding.locale_charmap #=> "646"
* LANG=ja
* Encoding.locale_charmap #=> "eucJP"
*
* The result is highly platform dependent.
* So Encoding.find(Encoding.locale_charmap) may cause an error.
* If you need some encoding object even for unknown locale,
* Encoding.find("locale") can be used.
*
*/
VALUE
rb_locale_charmap(VALUE klass)
{
#if NO_LOCALE_CHARMAP
return rb_usascii_str_new_cstr("US-ASCII");
#else
return locale_charmap(rb_usascii_str_new_cstr);
#endif
}
#if !NO_LOCALE_CHARMAP
static VALUE
enc_find_index(const char *name)
{
return (VALUE)rb_enc_find_index(name);
}
#endif
int
rb_locale_charmap_index(void)
{
#if NO_LOCALE_CHARMAP
return ENCINDEX_US_ASCII;
#else
return (int)locale_charmap(enc_find_index);
#endif
}
int
Init_enc_set_filesystem_encoding(void)
{
int idx;
#if NO_LOCALE_CHARMAP
idx = ENCINDEX_US_ASCII;
#elif defined _WIN32
char cp[SIZEOF_CP_NAME];
const UINT codepage = ruby_w32_codepage[1] ? ruby_w32_codepage[1] :
AreFileApisANSI() ? GetACP() : GetOEMCP();
CP_FORMAT(cp, codepage);
idx = rb_enc_find_index(cp);
if (idx < 0) idx = ENCINDEX_ASCII;
#elif defined __CYGWIN__
idx = ENCINDEX_UTF_8;
#else
idx = rb_enc_to_index(rb_default_external_encoding());
#endif
return idx;
}