Coverage Report

Created: 2024-02-13 07:03

/src/ruby/localeinit.c
Line
Count
Source (jump to first uncovered line)
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
0
{
41
0
    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
0
    codeset = nl_langinfo(CODESET);
57
0
    ASSUME(codeset);
58
#else
59
# error locale_charmap() is not implemented
60
#endif
61
0
    return (*conv)(codeset);
62
0
}
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
91
rb_locale_charmap(VALUE klass)
92
0
{
93
#if NO_LOCALE_CHARMAP
94
    return rb_usascii_str_new_cstr("US-ASCII");
95
#else
96
0
    return locale_charmap(rb_usascii_str_new_cstr);
97
0
#endif
98
0
}
99
100
#if !NO_LOCALE_CHARMAP
101
static VALUE
102
enc_find_index(const char *name)
103
0
{
104
0
    return (VALUE)rb_enc_find_index(name);
105
0
}
106
#endif
107
108
int
109
rb_locale_charmap_index(void)
110
0
{
111
#if NO_LOCALE_CHARMAP
112
    return ENCINDEX_US_ASCII;
113
#else
114
0
    return (int)locale_charmap(enc_find_index);
115
0
#endif
116
0
}
117
118
int
119
Init_enc_set_filesystem_encoding(void)
120
0
{
121
0
    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
135
0
    idx = rb_enc_to_index(rb_default_external_encoding());
136
0
#endif
137
0
    return idx;
138
0
}