132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2005 John Chapman. All rights reserved
|
|
4
|
|
5 license: BSD style: $(LICENSE)
|
|
6
|
|
7 version: Initial release: 2005
|
|
8
|
|
9 author: John Chapman
|
|
10
|
|
11 ******************************************************************************/
|
|
12
|
|
13 module tango.text.locale.Posix;
|
|
14
|
|
15 version (Posix)
|
|
16 {
|
|
17 alias tango.text.locale.Posix nativeMethods;
|
|
18
|
|
19 private import tango.core.Exception;
|
|
20 private import tango.text.locale.Data;
|
|
21 private import tango.stdc.ctype;
|
|
22 private import tango.stdc.posix.stdlib;
|
|
23 private import tango.stdc.string;
|
|
24 private import tango.stdc.time;
|
|
25 private import tango.stdc.locale;
|
|
26 private import tango.stdc.posix.time;
|
|
27
|
|
28 /*private extern(C) char* setlocale(int type, char* locale);
|
|
29 private extern(C) void putenv(char*);
|
|
30
|
|
31 private enum {LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES, LC_ALL, LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, LC_IDENTIFICATION};*/
|
|
32
|
|
33 int getUserCulture() {
|
|
34 char* env = getenv("LC_ALL");
|
|
35 if (!env || *env == '\0') {
|
|
36 env = getenv("LANG");
|
|
37 if (!env || *env == '\0')
|
|
38 throw new LocaleException("Neither LANG nor LC_ALL were found to be set. Please set for locale formatting to function.");
|
|
39 }
|
|
40
|
|
41 // getenv returns a string of the form <language>_<region>.
|
|
42 // Therefore we need to replace underscores with hyphens.
|
|
43 char* p = env;
|
|
44 int len;
|
|
45 while (*p) {
|
|
46 if (*p == '.'){
|
|
47 break;
|
|
48 }
|
|
49 if (*p == '_'){
|
|
50 *p = '-';
|
|
51 }
|
|
52 p++;
|
|
53 len++;
|
|
54 }
|
|
55
|
|
56 char[] s = env[0 .. len];
|
|
57 foreach (entry; CultureData.cultureDataTable) {
|
|
58 // todo: there is also a local compareString defined. Is it correct that here
|
|
59 // we use tango.text.locale.Data, which matches the signature?
|
|
60 if (tango.text.locale.Data.compareString(entry.name, s) == 0)
|
|
61 // todo: here was entry.id returned, which does not exist. Is lcid correct?
|
|
62 return entry.lcid;
|
|
63 }
|
|
64 return 0;
|
|
65 }
|
|
66
|
|
67 void setUserCulture(int lcid) {
|
|
68 char[] name;
|
|
69 try {
|
|
70 name = CultureData.getDataFromCultureID(lcid).name ~ ".utf-8";
|
|
71 }
|
|
72 catch(Exception e) {
|
|
73 return;
|
|
74 }
|
|
75
|
|
76 for(int i = 0; i < name.length; i++) {
|
|
77 if(name[i] == '.') break;
|
|
78 if(name[i] == '-') name[i] = '_';
|
|
79 }
|
|
80
|
|
81 putenv(("LANG=" ~ name).ptr);
|
|
82 setlocale(LC_CTYPE, name.ptr);
|
|
83 setlocale(LC_NUMERIC, name.ptr);
|
|
84 setlocale(LC_TIME, name.ptr);
|
|
85 setlocale(LC_COLLATE, name.ptr);
|
|
86 setlocale(LC_MONETARY, name.ptr);
|
|
87
|
|
88 version (GNU) {} else {
|
|
89 /* setlocale(LC_MESSAGES, name.ptr); */
|
|
90 }
|
|
91
|
|
92 setlocale(LC_PAPER, name.ptr);
|
|
93 setlocale(LC_NAME, name.ptr);
|
|
94 setlocale(LC_ADDRESS, name.ptr);
|
|
95 setlocale(LC_TELEPHONE, name.ptr);
|
|
96 setlocale(LC_MEASUREMENT, name.ptr);
|
|
97 setlocale(LC_IDENTIFICATION, name.ptr);
|
|
98 }
|
|
99
|
|
100 ulong getUtcTime() {
|
|
101 int t;
|
|
102 time(&t);
|
|
103 gmtime(&t);
|
|
104 return cast(ulong)((cast(long)t * 10000000L) + 116444736000000000L);
|
|
105 }
|
|
106
|
|
107 int compareString(int lcid, char[] stringA, uint offsetA, uint lengthA, char[] stringB, uint offsetB, uint lengthB, bool ignoreCase) {
|
|
108
|
|
109 void strToLower(char[] string) {
|
|
110 for(int i = 0; i < string.length; i++) {
|
|
111 string[i] = cast(char)(tolower(cast(int)string[i]));
|
|
112 }
|
|
113 }
|
|
114
|
|
115 char* tempCol = setlocale(LC_COLLATE, null), tempCType = setlocale(LC_CTYPE, null);
|
|
116 char[] locale;
|
|
117 try {
|
|
118 locale = CultureData.getDataFromCultureID(lcid).name ~ ".utf-8";
|
|
119 }
|
|
120 catch(Exception e) {
|
|
121 return 0;
|
|
122 }
|
|
123
|
|
124 setlocale(LC_COLLATE, locale.ptr);
|
|
125 setlocale(LC_CTYPE, locale.ptr);
|
|
126
|
|
127 char[] s1 = stringA[offsetA..offsetA+lengthA].dup,
|
|
128 s2 = stringB[offsetB..offsetB+lengthB].dup;
|
|
129 if(ignoreCase) {
|
|
130 strToLower(s1);
|
|
131 strToLower(s2);
|
|
132 }
|
|
133
|
|
134 int ret = strcoll(s1[offsetA..offsetA+lengthA].ptr, s2[offsetB..offsetB+lengthB].ptr);
|
|
135
|
|
136 setlocale(LC_COLLATE, tempCol);
|
|
137 setlocale(LC_CTYPE, tempCType);
|
|
138
|
|
139 return ret;
|
|
140 }
|
|
141
|
|
142 debug(UnitTest)
|
|
143 {
|
|
144 unittest
|
|
145 {
|
|
146 int c = getUserCulture();
|
|
147 assert(compareString(c, "Alphabet", 0, 8, "Alphabet", 0, 8, false) == 0);
|
|
148 assert(compareString(c, "Alphabet", 0, 8, "alphabet", 0, 8, true) == 0);
|
|
149 assert(compareString(c, "Alphabet", 0, 8, "alphabet", 0, 8, false) != 0);
|
|
150 assert(compareString(c, "lphabet", 0, 7, "alphabet", 0, 8, true) != 0);
|
|
151 assert(compareString(c, "Alphabet", 0, 8, "lphabet", 0, 7, true) != 0);
|
|
152 }
|
|
153 }
|
|
154 }
|