On Wed, 2011-06-29 at 14:41 +0200, Axel Freyn wrote: > Hi Eric, > > Would you please post your test os(linux kernel version) and which g++ > > version you use, especially when you pass the test > > ------------- > > #include <iostream> > > #include <fstream> > > #include <string> > > //#include <cstring> > > > > using namespace std; > > int main(int argc, char *argv[]) { > > > > /* try { > > std::locale::global(std::locale("")); > > } catch ( ... ) { }; */ > > > > wstring ws2 = L"Euro: \x20ac"; > > wofstream out("unicode.txt"); > > if(not out.good()) > > cerr << "Error opening output file" << endl; > > //const char *name = "el_GR.utf8"; > > const char *name = "en_US.utf8"; > > if(argc == 2) > > name = argv[1]; > > cout << "trying to access locale " << name << endl; > > locale loc; > > try{ > > loc = locale(name); > > cout << "Generated locale " << loc.name() << endl; > > }catch( exception &e){ > > cerr << "Couldn't generate locale " << name << ": " << e.what() << > > endl; > > } > > out.imbue(loc); > > if(not out.good()) > > cerr << "Error when setting the locale" << endl; > > out << ws2<< endl; > > if(not out.good()) > > cerr << "Error when writing to file" << endl; > > } > > ------------ > > You could try to run the test-program with "strace", like > strace ./test en_US.utf8 > this tells at least what the code is trying to do while loading the > encoding. On my machine I get the following for an EXISTING encoding: > > open("unicode.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 > fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0 > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb8588e6000 > write(1, "trying to access locale fr_FR.ut"..., 35trying to access locale fr_FR.utf8 > ) = 35 > open("/usr/lib/locale/locale-archive", O_RDONLY) = 4 > fstat(4, {st_mode=S_IFREG|0644, st_size=1527584, ...}) = 0 > mmap(NULL, 1527584, PROT_READ, MAP_PRIVATE, 4, 0) = 0x7fb85875d000 > close(4) = 0 > open("/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = 4 > fstat(4, {st_mode=S_IFREG|0644, st_size=26048, ...}) = 0 > mmap(NULL, 26048, PROT_READ, MAP_SHARED, 4, 0) = 0x7fb8588df000 > close(4) = 0 > write(1, "Generated locale fr_FR.utf8\n", 28Generated locale fr_FR.utf8 > ) = 28 > > > And for a NON-EXISTING encoding (fr_FF.utf8): > > open("unicode.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 > fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0 > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc99aff4000 > write(1, "trying to access locale fr_FF.ut"..., 35trying to access locale fr_FF.utf8 > ) = 35 > open("/usr/lib/locale/locale-archive", O_RDONLY) = 4 > fstat(4, {st_mode=S_IFREG|0644, st_size=1527584, ...}) = 0 > mmap(NULL, 1527584, PROT_READ, MAP_PRIVATE, 4, 0) = 0x7fc99ae6b000 > close(4) = 0 > open("/usr/share/locale/locale.alias", O_RDONLY) = 4 > fstat(4, {st_mode=S_IFREG|0644, st_size=2570, ...}) = 0 > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc99aff3000 > read(4, "# Locale name alias data base.\n#"..., 4096) = 2570 > read(4, "", 4096) = 0 > close(4) = 0 > munmap(0x7fc99aff3000, 4096) = 0 > open("/usr/lib/locale/fr_FF.utf8/LC_CTYPE", O_RDONLY) = -1 ENOENT (No such file or directory) > open("/usr/lib/locale/fr_FF/LC_CTYPE", O_RDONLY) = -1 ENOENT (No such file or directory) > open("/usr/lib/locale/fr.utf8/LC_CTYPE", O_RDONLY) = -1 ENOENT (No such file or directory) > open("/usr/lib/locale/fr/LC_CTYPE", O_RDONLY) = -1 ENOENT (No such file or directory) > write(2, "Couldn't generate locale ", 25Couldn't generate locale ) = 25 > > So, I suggest for my machine: > - it searches in "/usr/lib/locale/locale-archive" for the encoding > - if it is found, it loads the encoding from "/usr/lib/gconv/gconv-modules.cache" > - if it is NOT found, it searches for related directories in > /usr/lib/locale/ , trying to open a file LC_CTYPE > > If your compiler/os/standard-library has working locale-support, I would > expect it to do something similar -- if the locale-support is > deactivated in the compiler, one should see it here. > > Other opinions? > > Axel --------------------------------------------------------------- #include <iostream> #include <fstream> #include <string> //#include <cstring> using namespace std; int main(int argc, char *argv[]) { /* try { std::locale::global(std::locale("")); } catch ( ... ) { }; */ wstring ws2 = L"Euro: \x20ac"; wofstream out("unicode.txt"); if(not out.good()) cerr << "Error opening output file" << endl; //const char *name = "el_GR.utf8"; const char *name = "en_US.utf8"; if(argc == 2) name = argv[1]; cout << "trying to access locale " << name << endl; locale loc; try{ loc = locale(name); cout << "Generated locale " << loc.name() << endl; }catch( exception &e){ cerr << "Couldn't generate locale " << name << ": " << e.what() << endl; } out.imbue(loc); if(not out.good()) cerr << "Error when setting the locale" << endl; out << ws2<< endl; if(not out.good()) cerr << "Error when writing to file" << endl; open("unicode.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb8588e6000 write(1, "trying to access locale fr_FR.ut"..., 35trying to access locale fr_FR.utf8 ) = 35 open("/usr/lib/locale/locale-archive", O_RDONLY) = 4 fstat(4, {st_mode=S_IFREG|0644, st_size=1527584, ...}) = 0 mmap(NULL, 1527584, PROT_READ, MAP_PRIVATE, 4, 0) = 0x7fb85875d000 close(4) = 0 open("/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = 4 fstat(4, {st_mode=S_IFREG|0644, st_size=26048, ...}) = 0 mmap(NULL, 26048, PROT_READ, MAP_SHARED, 4, 0) = 0x7fb8588df000 close(4) = 0 write(1, "Generated locale fr_FR.utf8\n", 28Generated locale fr_FR.utf8 ) = 28 } ------------------------------------ root@eric-laptop:/home/eric/cppcookbook# g++ testlocale1.cpp testlocale1.cpp:39:49: error: invalid suffix "trying" on integer constant testlocale1.cpp:49:43: error: invalid suffix "Generated" on integer constant testlocale1.cpp: In function ‘int main(int, char**)’: testlocale1.cpp:36:21: error: ‘O_WRONLY’ was not declared in this scope testlocale1.cpp:36:30: error: ‘O_CREAT’ was not declared in this scope testlocale1.cpp:36:38: error: ‘O_TRUNC’ was not declared in this scope testlocale1.cpp:36:51: error: ‘open’ was not declared in this scope testlocale1.cpp:37:1: error: expected ‘;’ before ‘fstat’ testlocale1.cpp:37:62: error: expected primary-expression before ‘)’ token testlocale1.cpp:37:62: error: expected ‘;’ before ‘)’ token testlocale1.cpp:42:54: error: expected primary-expression before ‘)’ token testlocale1.cpp:42:54: error: expected ‘;’ before ‘)’ token testlocale1.cpp:46:52: error: expected primary-expression before ‘)’ token testlocale1.cpp:46:52: error: expected ‘;’ before ‘)’ token ---------------------------------------------------- plus, I get an email from someone who work in linux kernel 3.0 about this locale issue on g++/ubuntu -------- Hello Eric, The kernel has nothing to do with this. It is a C++ library issue only. Your code looks fine. It seems that locale support is lacking in the STL that comes with g++ on many platforms. I tested it here on Mac OS X (Leopard) with GCC 4.0.1 and also found that it did not work. I have only needed very little locale support in the projects I have been involved in and I believe I used the C library functions when I needed it, even though the project was C++. It is sad really, but unless you have a lot of time on your hands to fix the library, I guess there is not much to do about it :) About the kernel, yes it is written in C and no, no part of it is written in C++, nor is it likely to be any time soon. I hope this helps. ---------------------------------------------- need more advice and thanks a lot in advance Eric