#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ManagedStatic.h" #include <cassert> #include <xlocale.h> namespace { struct locale_holder { locale_holder() : l(newlocale(LC_CTYPE_MASK,"en_US.UTF-8",LC_GLOBAL_LOCALE)) { assert(NULL!=l); } ~locale_holder() { freelocale(l); } int mbswidth(llvm::SmallString<16> s) const { // this implementation assumes no '\0' in s assert(s.size()==strlen(s.c_str())); size_t size = mbstowcs_l(NULL,s.c_str(),0,l); assert(size!=(size_t)-1); if (size==0) return 0; llvm::SmallVector<wchar_t,200> ws(size); size = mbstowcs_l(&ws[0],s.c_str(),ws.size(),l); assert(ws.size()==size); return wcswidth_l(&ws[0],ws.size(),l); } int isprint(int c) const { return iswprint_l(c,l); } private: locale_t l; }; llvm::ManagedStatic<locale_holder> l; } namespace llvm { namespace sys { namespace locale { int columnWidth(StringRef s) { int width = l->mbswidth(s); assert(width>=0); return width; } bool isPrint(int c) { return l->isprint(c); } } } }