mirror of
https://bitbucket.org/smil3y/katie.git
synced 2025-02-25 03:12:56 +00:00
reimplement locale name to language, script and country splitting via ICU
Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
This commit is contained in:
parent
ef0c068818
commit
118bbe0109
1 changed files with 31 additions and 72 deletions
|
@ -232,81 +232,40 @@ const QLocalePrivate *QLocalePrivate::findLocale(QLocale::Language language, QLo
|
||||||
return &localeTbl[0];
|
return &localeTbl[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int bcp47max = 11; // worst case according to BCP47
|
|
||||||
|
|
||||||
static bool parse_locale_tag(const QString &input, int &i, QString *result, const QString &separators)
|
|
||||||
{
|
|
||||||
*result = QString(bcp47max, Qt::Uninitialized);
|
|
||||||
QChar *pch = result->data();
|
|
||||||
const QChar *uc = input.data() + i;
|
|
||||||
const int l = input.length();
|
|
||||||
int size = 0;
|
|
||||||
for (; i < l && size < bcp47max; ++i, ++size) {
|
|
||||||
if (separators.contains(*uc))
|
|
||||||
break;
|
|
||||||
if (! ((uc->unicode() >= 'a' && uc->unicode() <= 'z') ||
|
|
||||||
(uc->unicode() >= 'A' && uc->unicode() <= 'Z') ||
|
|
||||||
(uc->unicode() >= '0' && uc->unicode() <= '9')) ) // latin only
|
|
||||||
return false;
|
|
||||||
*pch++ = *uc++;
|
|
||||||
}
|
|
||||||
result->truncate(size);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QString &cntry)
|
bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QString &cntry)
|
||||||
{
|
{
|
||||||
const int length = name.length();
|
const QByteArray latinname = name.toLatin1();
|
||||||
|
char getbuffer[20];
|
||||||
lang = script = cntry = QString();
|
UErrorCode error = U_ZERO_ERROR;
|
||||||
|
const int langresult = uloc_getLanguage(latinname.constData(), getbuffer, sizeof(getbuffer), &error);
|
||||||
const QString separators = QLatin1String("_-.@");
|
if (Q_UNLIKELY(U_FAILURE(error))) {
|
||||||
enum ParserState { NoState, LangState, ScriptState, CountryState };
|
qWarning("qt_splitLocaleName: uloc_getLanguage(%s) failed %s",
|
||||||
ParserState state = LangState;
|
latinname.constData(), u_errorName(error));
|
||||||
for (int i = 0; i < length && state != NoState; ) {
|
return false;
|
||||||
QString value;
|
|
||||||
if (!parse_locale_tag(name, i, &value, separators) ||value.isEmpty())
|
|
||||||
break;
|
|
||||||
QChar sep = i < length ? name.at(i) : QChar();
|
|
||||||
switch (state) {
|
|
||||||
case LangState:
|
|
||||||
if (!sep.isNull() && !separators.contains(sep)) {
|
|
||||||
state = NoState;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lang = value;
|
|
||||||
if (i == length) {
|
|
||||||
// just language was specified
|
|
||||||
state = NoState;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
state = ScriptState;
|
|
||||||
break;
|
|
||||||
case ScriptState: {
|
|
||||||
// if it wasn't a script, maybe it is a country then?
|
|
||||||
cntry = value;
|
|
||||||
state = NoState;
|
|
||||||
for (qint16 ii = 0; ii < scriptTblSize; ii++) {
|
|
||||||
if (QString::fromLatin1(scriptTbl[ii].code) == value) {
|
|
||||||
script = value;
|
|
||||||
state = CountryState;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CountryState:
|
|
||||||
cntry = value;
|
|
||||||
state = NoState;
|
|
||||||
break;
|
|
||||||
case NoState:
|
|
||||||
// shouldn't happen
|
|
||||||
qWarning("QLocale: This should never happen");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
return lang.length() == 2 || lang.length() == 3;
|
lang = QString::fromLatin1(getbuffer, langresult);
|
||||||
|
|
||||||
|
error = U_ZERO_ERROR;
|
||||||
|
memset(getbuffer, 0, sizeof(getbuffer));
|
||||||
|
const int scriptresult = uloc_getScript(latinname.constData(), getbuffer, sizeof(getbuffer), &error);
|
||||||
|
if (Q_UNLIKELY(U_FAILURE(error))) {
|
||||||
|
qWarning("qt_splitLocaleName: uloc_getScript(%s) failed %s",
|
||||||
|
latinname.constData(), u_errorName(error));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
script = QString::fromLatin1(getbuffer, scriptresult);
|
||||||
|
|
||||||
|
error = U_ZERO_ERROR;
|
||||||
|
memset(getbuffer, 0, sizeof(getbuffer));
|
||||||
|
const int countryresult = uloc_getCountry(latinname.constData(), getbuffer, sizeof(getbuffer), &error);
|
||||||
|
if (Q_UNLIKELY(U_FAILURE(error))) {
|
||||||
|
qWarning("qt_splitLocaleName: uloc_getCountry(%s) failed %s",
|
||||||
|
latinname.constData(), u_errorName(error));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cntry = QString::fromLatin1(getbuffer, countryresult);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QLocalePrivate::getLangAndCountry(const QString &name, QLocale::Language &lang,
|
void QLocalePrivate::getLangAndCountry(const QString &name, QLocale::Language &lang,
|
||||||
|
|
Loading…
Add table
Reference in a new issue