comparison tango/tango/text/locale/Posix.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
comparison
equal deleted inserted replaced
131:5825d48b27d1 132:1700239cab2e
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 }