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.stringz; 25 private import tango.stdc.locale; 26 27 /*private extern(C) char* setlocale(int type, char* locale); 28 private extern(C) void putenv(char*); 29 30 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};*/ 31 32 int getUserCulture() { 33 char* env = getenv("LC_ALL"); 34 if (!env || *env == '\0') { 35 env = getenv("LANG"); 36 } 37 38 // getenv returns a string of the form <language>_<region>. 39 // Therefore we need to replace underscores with hyphens. 40 const(char)[] s; 41 if (env){ 42 char[] s2 = fromStringz(env).dup; 43 foreach (ref c; s2) 44 if (c == '.') 45 break; 46 else 47 if (c == '_') 48 c = '-'; 49 s=s2; 50 } else { 51 s="en-US"; 52 } 53 foreach (entry; CultureData.cultureDataTable) { 54 // todo: there is also a local compareString defined. Is it correct that here 55 // we use tango.text.locale.Data, which matches the signature? 56 if (tango.text.locale.Data.compareString(entry.name, s) == 0) 57 return entry.lcid; 58 } 59 60 foreach (entry; CultureData.cultureDataTable) { 61 // todo: there is also a local compareString defined. Is it correct that here 62 // we use tango.text.locale.Data, which matches the signature? 63 if (tango.text.locale.Data.compareString(entry.name, "en-US") == 0) 64 return entry.lcid; 65 } 66 return 0; 67 } 68 69 import tango.io.Stdout; 70 import tango.stdc.stdio; 71 72 void setUserCulture(int lcid) { 73 char[] name; 74 try { 75 name = CultureData.getDataFromCultureID(lcid).name ~ ".utf-8"; 76 } 77 catch(Exception e) { 78 return; 79 } 80 81 for(int i = 0; i < name.length; i++) { 82 if(name[i] == '.') break; 83 if(name[i] == '-') name[i] = '_'; 84 } 85 86 putenv(("LANG=" ~ name).ptr); 87 setlocale(LC_CTYPE, name.ptr); 88 setlocale(LC_NUMERIC, name.ptr); 89 setlocale(LC_TIME, name.ptr); 90 setlocale(LC_COLLATE, name.ptr); 91 setlocale(LC_MONETARY, name.ptr); 92 93 version (GNU) {} else { 94 /* setlocale(LC_MESSAGES, name.ptr); */ 95 } 96 97 setlocale(LC_PAPER, name.ptr); 98 setlocale(LC_NAME, name.ptr); 99 setlocale(LC_ADDRESS, name.ptr); 100 setlocale(LC_TELEPHONE, name.ptr); 101 setlocale(LC_MEASUREMENT, name.ptr); 102 setlocale(LC_IDENTIFICATION, name.ptr); 103 } 104 105 int compareString(int lcid, const(char)[] stringA, size_t offsetA, size_t lengthA, const(char)[] stringB, size_t offsetB, size_t lengthB, bool ignoreCase) { 106 107 void strToLower(char[] string) { 108 for(int i = 0; i < string.length; i++) { 109 string[i] = cast(char)(tolower(cast(int)string[i])); 110 } 111 } 112 113 char* tempCol = setlocale(LC_COLLATE, null), tempCType = setlocale(LC_CTYPE, null); 114 const(char)[] locale; 115 try { 116 locale = CultureData.getDataFromCultureID(lcid).name ~ ".utf-8"; 117 } 118 catch(Exception e) { 119 return 0; 120 } 121 122 setlocale(LC_COLLATE, locale.ptr); 123 setlocale(LC_CTYPE, locale.ptr); 124 125 char[] s1 = stringA[offsetA..offsetA+lengthA] ~ "\0", 126 s2 = stringB[offsetB..offsetB+lengthB] ~ "\0"; 127 if(ignoreCase) { 128 strToLower(s1); 129 strToLower(s2); 130 } 131 132 int ret = strcoll(s1.ptr, s2.ptr); 133 134 setlocale(LC_COLLATE, tempCol); 135 setlocale(LC_CTYPE, tempCType); 136 137 return ret; 138 } 139 140 debug(UnitTest) 141 { 142 unittest 143 { 144 int c = getUserCulture(); 145 assert(compareString(c, "Alphabet", 0, 8, "Alphabet", 0, 8, false) == 0); 146 assert(compareString(c, "Alphabet", 0, 8, "alphabet", 0, 8, true) == 0); 147 assert(compareString(c, "Alphabet", 0, 8, "alphabet", 0, 8, false) != 0); 148 assert(compareString(c, "lphabet", 0, 7, "alphabet", 0, 8, true) != 0); 149 assert(compareString(c, "Alphabet", 0, 8, "lphabet", 0, 7, true) != 0); 150 assert(compareString(c, "Alphabet", 0, 7, "ZAlphabet", 1, 7, false) == 0); 151 } 152 } 153 }