1#include "llvm/ADT/SmallVector.h" 2#include "llvm/ADT/SmallString.h" 3#include "llvm/Support/ManagedStatic.h" 4#include <cassert> 5#include <xlocale.h> 6 7 8namespace { 9 struct locale_holder { 10 locale_holder() 11 : l(newlocale(LC_CTYPE_MASK,"en_US.UTF-8",LC_GLOBAL_LOCALE)) 12 { 13 assert(NULL!=l); 14 } 15 ~locale_holder() { 16 freelocale(l); 17 } 18 19 int mbswidth(llvm::SmallString<16> s) const { 20 // this implementation assumes no '\0' in s 21 assert(s.size()==strlen(s.c_str())); 22 23 size_t size = mbstowcs_l(NULL,s.c_str(),0,l); 24 assert(size!=(size_t)-1); 25 if (size==0) 26 return 0; 27 llvm::SmallVector<wchar_t,200> ws(size); 28 size = mbstowcs_l(&ws[0],s.c_str(),ws.size(),l); 29 assert(ws.size()==size); 30 return wcswidth_l(&ws[0],ws.size(),l); 31 } 32 33 int isprint(int c) const { 34 return iswprint_l(c,l); 35 } 36 37 private: 38 39 locale_t l; 40 }; 41 42 llvm::ManagedStatic<locale_holder> l; 43} 44 45namespace llvm { 46namespace sys { 47namespace locale { 48 49int columnWidth(StringRef s) { 50 int width = l->mbswidth(s); 51 assert(width>=0); 52 return width; 53} 54 55bool isPrint(int c) { 56 return l->isprint(c); 57} 58 59} 60} 61} 62