2012-04-18 04:03:03 +08:00
|
|
|
#include "llvm/ADT/SmallString.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2012-04-18 04:03:03 +08:00
|
|
|
#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);
|
2012-04-18 08:40:23 +08:00
|
|
|
assert(size!=(size_t)-1);
|
2012-04-18 04:03:03 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|