> Угу. Я тож сначала подумал, что они от ветвления решили избавиться табличкой
> на 256 элементов. Но ведь нет, на 256 байт таблички они
> пожидились и условие всё равно нужно.Так не пожидились! Я тоже изначально не так понял, поскольку наблюдаемый вариант кажется сюром. Там две таблицы, суммой в 512 байт, из которых используются 2*26.
Вот это в Си инициализирует 0x41-й (в случае исходника в ASCII) элемент значением 'a', а остальные 255 элементов значением 0:
static const unsigned char maptolower[256] = {
['A'] = 'a',
};
При выборке значение символа используется как индекс массива, как в команде xlat от x86.
Таблицы могли бы иметь смысл, поскольку раньше детей пугали словами "source character set" и "EBCDIC", но тогда бы в них следовало писать не 'A', а значения из соответствующего раздела OSI/ISO.
> Хрен угадаешь, о чём они думали, когда писали. Может они скопипастили откуда-то
> код под utf8, а потом выкинули ненужное? С utf8 реально таблички
> нужны, т.к. все эти этнические алфавиты себя иногда странно ведут при
> попытке сменить регистр.
Не знаю. Признаться, я немного опасаюсь вникать в этот код. Когда-то вывел эмпирическое правило: если нашёл рядом две ошибки, обязательно где-то есть и третья.
if (ISC_LIKELY(CASEFULLYLOWER(header))) {
for (size_t i = 0; i < name->length; i++) {
uint8_t c = name->ndata[i];
if (c >= 'A' && c <= 'Z') {
name->ndata[i] = maptolower[c];
}
}
} else {
for (size_t i = 0; i < name->length; i++) {
uint8_t c = name->ndata[i]; if (mask == (1 << 7)) {
bits = header->upper[i / 8];
mask = 1;
} else {
mask <<= 1;
}
if (c >= 'a' && c <= 'z') {
if ((bits & mask) != 0) {
name->ndata[i] = maptoupper[c];
}
} else if (c >= 'A' && c <= 'Z') {
if ((bits & mask) == 0) {
name->ndata[i] = maptolower[c];
}
}
}
}
https://gitlab.isc.org/isc-projects/bind9/-/blob/9f13e610417...