LINUX.ORG.RU

В Си предложили добавить switch-case для строк

 , ,


0

4

Привет, чат!

Спустя много лет, в язык Си наконец предложено добавить возможность использовать выражение switch-case для строк. Например, можно будет писать вот такое:

const char *s = get_some_string();

switch(s) {
case "this":
  handle_this();
  break;
case "that":
  handle_that();
  break;
default:
  handle_other();
  break;
}

Таким образом, в Си будет чуть меньше способов отстрелить себе ноги.

Ссылка на предложение: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3895.pdf



Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от shdown

А вообще, мне wcwidth нужен для того, чтобы понять, где обрезать текст. Если оно на каком-то наркоманском вводе покажет больше, чем нужно, — это норм. Главное, что не меньше.

А этот твой libicu вообще не знает про терминоль. И как ты с помощью него это определять собрался — непонятно.

shdown ★★
()
Ответ на: комментарий от shdown

А можешь показать хоть один пример софта, кроме konsole, который воспринимает их как один символ?

У меня в системе работает с любым софтом на Qt. А с софтом на GTK не работает.

firefox, ты говоришь, тоже

Не. В поле ввода Firefox рисует один символ. При рендере готовой страницы – два. Прозреваю, потому что что шревты разные.

yorshka
() автор топика
Ответ на: комментарий от shdown

А вообще, мне wcwidth нужен для того, чтобы понять, где обрезать текст. Если оно на каком-то наркоманском вводе покажет больше, чем нужно, — это норм. Главное, что не меньше.

А этот твой libicu вообще не знает про терминоль. И как ты с помощью него это определять собрался — непонятно.

Ну ЛОЛ же ну.

yorshka
() автор топика
Ответ на: комментарий от yorshka

Ну ЛОЛ же ну.

Ну и чего мне твой анализ рубежей? Не, ты покажи, как ты собираешься с libicu посчитать эту хрень для терминоля.

Хорошо, установил я твой konsole. Он сдвигает курсор на два знакоместа. Как мне это посчитать с помощью libicu?

#include <unicode/ubrk.h>
#include <unicode/utypes.h>
#include <unicode/ustring.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

int count_grapheme_clusters(const UChar *text, int32_t length) {
    UErrorCode status = U_ZERO_ERROR;
    int count = 0;

    // Create a character break iterator (grapheme cluster boundaries)
    UBreakIterator *bi = ubrk_open(UBRK_CHARACTER, "en_US", text, length, &status);
    if (U_FAILURE(status)) {
        fprintf(stderr, "Error opening break iterator: %s\n", u_errorName(status));
        return -1;
    }

    int32_t boundary = ubrk_first(bi);
    while (boundary != UBRK_DONE) {
        int32_t next = ubrk_next(bi);
        if (next == UBRK_DONE) break;
        count++;
        boundary = next;
    }

    ubrk_close(bi);
    return count;
}

int main() {
    enum { N = 2048 };

    UChar text[N];
    UErrorCode status = U_ZERO_ERROR;

    size_t nline = 0;
    char *line = NULL;
    if (getline(&line, &nline, stdin) <= 0) {
        fprintf(stderr, "getline() failed.\n");
        return 1;
    }

    if (strlen(line) && line[strlen(line) - 1] == '\n') {
        line[strlen(line) - 1] = '\0';
    }

    int32_t destLength;
    u_strFromUTF8(text, N, &destLength, line, -1, &status);

    if (U_FAILURE(status)) {
        fprintf(stderr, "Conversion error: %s\n", u_errorName(status));
        return 1;
    }

    int graphemes = count_grapheme_clusters(text, destLength);
    printf("Grapheme clusters: %d\n", graphemes);
    printf("UTF-16 code units: %d\n", destLength);

    return 0;
}

Она говорит, что 1 grapheme cluster.

shdown ★★
()
Последнее исправление: shdown (всего исправлений: 1)
Ответ на: комментарий от shdown

Ну и чего мне твой анализ рубежей?

Вот для этого он нужен, балда:

А вообще, мне wcwidth нужен для того, чтобы понять, где обрезать текст.

Он сдвигает курсор на два знакоместа. Как мне это посчитать с помощью libicu?

Теперь ты понимаешь, что юникод – это тебе не в тапки срать? Повторю ещё раз: количество знакомест зависит от графемы и шрифта. Мой пример выше – два эмоджи, склеенных в один через zero-width joiner. Если шрифт поддерживает эту комбинацию, будет одно знакоместо. Если не поддерживает, будет два.

Чтобы подсчитать всё это, тебе нужна библиотека Harfbuzz, потому что – как я писал выше – шейпер из libicu выкинули. И, да, там уже нет никаких знакомест, там уже пиксели высчитываются. См. примерно вот сюда.

yorshka
() автор топика
Ответ на: комментарий от yorshka

Не. В поле ввода Firefox рисует один символ. При рендере готовой страницы – два. Прозреваю, потому что что шревты разные.

У меня с большой задержкой рисует. Сначала два показывает, потом через секунд десть уже один.

Dr64h ★★★★
()

Не самая плохая идея!

vbr ★★★★★
()
Ответ на: комментарий от Dr64h

Прикол, теперь не могу повторить. При перезагрузке страницы всё наоборот, рисуется сначала один чубрик и через секунду «рука-лицо и стрелка», хотя при первой загрузке, сначала были две кракозябры, потом чубрик.

Dr64h ★★★★
()
Ответ на: комментарий от Dr64h

Опять же, ставлю на подгрузку шревтов и твой тормозной комп. Но, в любом случае, тут суть в том, что символов не пять, как это говорит хвалёная функция wcswidth.

К слову

If a nonprintable wide character occurs among these characters, -1 is returned.

Оно должно вообще на ZWJ тут выругаться, ибо

The zero-width joiner (ZWJ) is a non-printing character used in the computerized typesetting of some complex scripts such as the Arabic script or any Indic script.

Либо же я чего-то не понимаю в этой документации. Как бы то ни было, поведение wcswidth в некорректно с любой стороны.

yorshka
() автор топика
Ответ на: комментарий от yorshka

как без <wchar.h> понять, сколько знакомест в терминале займёт такая-то строка

Чтобы подсчитать всё это, тебе нужна библиотека Harfbuzz

И, да, там уже нет никаких знакомест

Да ты же поехавший! Терминал оперирует знакоместами, а не пикселями. Можно запросить, на каком столбце сейчас курсор (целое число). А для пикселей вот ANSI escape code нет.

shdown ★★
()
Ответ на: комментарий от shdown

Терминал оперирует знакоместами, а не пикселями.

Нет. Раньше оперировал, во времена телетайпов и обязательных моноширинных шрифтов. Как только мы добавляем эмоджи, лигатуры и прочие юникодные радости, все это едет в лес.

Ситуация достаточно шизофреническая выходит, да. Мы притворяемся, что у нас терминал с квадратно-гнездовым размещением знаков, а потом суём в него эмоджи с какающим беременным мужчиной (который на самом деле три эмоджи и два ZWJ), от чего тот сходит с ума.

Можно запросить, на каком столбце сейчас курсор (целое число).

Запросить ты можешь, но ответ, как ты уже смог увидеть, тебе не понравится.

А для пикселей вот ANSI escape code нет.

Но твой терминал рисует юникод, а не ANSI. Речь об этом.

yorshka
() автор топика
Ответ на: комментарий от yorshka

обязательных моноширинных шрифтов

Не, ну в порядке извращения ты можешь заставить терминал использовать не-моноширинный шрифт, но он всё равно будет рисовать символы в сетке с постоянной шириной.

Мы притворяемся, что у нас терминал с квадратно-гнездовым размещением знаков, а потом суём в него эмоджи с какающим беременным мужчиной (который на самом деле три эмоджи и два ZWJ), от чего тот сходит с ума.

Нет, просто есть символы, которые занимают одно знакоместо, и есть те, которые занимают два (а есть те, которые занимают ноль). Ещё до популярности юникода была half-width katakana и full-width katakana. А кандзи всегда два знакоместа занимают. А есть ещё английские буквы, которые занимают два знакоместа! TRY ENTERING THIS.

Короче, общая концепция вполне sound, просто не все терминоли соглашаются между собой, какие code points сколько знакомест занимают. Есть proposal для стандартизации этой фигни.

Запросить ты можешь, но ответ, как ты уже смог увидеть, тебе не понравится.

Почему не понравится? Он что, врёт?

> А для пикселей вот ANSI escape code нет.

Но твой терминал рисует юникод, а не ANSI. Речь об этом.

Ты перепутал ANSI с ASCII?

shdown ★★
()
Последнее исправление: shdown (всего исправлений: 4)
Ответ на: комментарий от shdown

Не, ну в порядке извращения ты можешь заставить терминал использовать не-моноширинный шрифт, но он всё равно будет ПЫТАТЬСЯ рисовать символы в сетке с постоянной шириной.

Поправил. Не факт, что всегда будет получаться успешно.

Короче, общая концепция вполне sound, просто не все терминоли соглашаются между собой, какие code points сколько знакомест занимают. Есть proposal для стандартизации этой фигни.

Я не про концепцию здесь, а про реальное состояние вещей. Идея, конечно, вполне адекватно, кто бы спорил-то.

Запросить ты можешь, но ответ, как ты уже смог увидеть, тебе не понравится.

Почему не понравится? Он что, врёт?

А ты не заметил? Здесь правда пять символов?

$ cat emoji 
🤦🏼‍♂
$ ./foo < emoji 
5

Ты перепутал ANSI с ASCII?

Нет.

yorshka
() автор топика
Ответ на: комментарий от yorshka

> > > Можно запросить, на каком столбце сейчас курсор (целое число).

> > Запросить ты можешь, но ответ, как ты уже смог увидеть, тебе не понравится.

> Почему не понравится? Он что, врёт?

А ты не заметил? Здесь правда пять символов?

wcswidth не запрашивает позицию курсора у терминала. Когда у терминала запрашивают позицию курсора, он не врёт.

Ты забываешь контекст?

shdown ★★
()
Ответ на: комментарий от shdown

wcswidth не запрашивает позицию курсора у терминала. Когда у терминала запрашивают позицию курсора, он не врёт.

Тогда верно. Я думал, ты хотел посчитать позицию через длину выведенного с начала строки.

С другой стороны, я вполне видел глюки, когда курсор мигал в середине последнего выведенного символа, потому что он оказался длиннее. Как раз из-за причин выше.

yorshka
() автор топика
Ответ на: комментарий от yorshka

я не знаком с растом и изучать пока не готов, но считаю его допустимым языком для молодого поколения программистов

sni4ok
()
Ответ на: комментарий от sni4ok

но мне только 42, я даже младше элона маска

Мир несправедлив, я понимаю. Илон Маск трахает топ-моделей и голливудских актрис, заделывая с ними детей. А у тебя уже деменция и неспособность осилить сраный быдлоязычок для хипстеров, который те уже в ведро протащили :((((((((

yorshka
() автор топика
Ответ на: комментарий от yorshka

вы так пишите как будто элон маск не может являться эталоном православного гражданина

sni4ok
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.