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