Комментарии 42
По моему самое главное в терминале - это создание пары pty master и pty slave и ее соответствующая настройка. Вы не стали ее использовать?
Я не стал. Даже если честно не знал о них, я порылся в некоторых других репозиториях даже, нету такого(
Так он же пишет не эмулятор терминала (xterm, Konsole, xfce-terminal, Gnome Terminal) и другие инструменты (tmux, screen), которые сопоставляют псевдотерминальные дескрипторы с выводом конкретного приложения, а командный интерпретатор для которого уже это это сделано эмуоятром терминала.
Свой minishell пишут на 5 уровне ( из 21 ) в школе21
И на Гите есть куча тестов. ( minishell ecole42 test )
Прогоните хоть какой
инициализирует его до нуля
что простите? до какого нуля? кроме того в описаниях появляются разные еклмнэейки при том что показанные вами сигнатуры не принимают аргументов.
И именно благодаря более свободной лицензии, чем GNU GPL (открытость не значит свобода).
более свободный это уже public domain, что явно не относится к большинству подобного софта.
(kolibri os, os/2) используется именно gcc.
kolibri вообще на ассемблере пишется и компилятор их ассемблера написан на нём же и к gcc отношения как такового не имеет.
if (strcmp(color_name, "RED") == 0) { color_value = RED; } else if (strcmp(color_name, "GREEN") == 0) { color_value = GREEN; } else
а чего их вам в статичный массив не поскладировать и циклом проверять? два десятка стрёмных строчек превращаются в красивый список, цикл и одну стрёмную строчку.
fprintf(stderr, "%s%s%s%s%s %s\n", RESET,
дабы не теребить лишний раз форматтер можно использовать факт, что строковые литералы не разделённые запятыми считаются за одну строку. То бишь
fprintf(stderr, RESET "%s%s%s" RESET " %s\n"
, color, format, msgtype_string, message);
Т.к. макрос также развернётся в строковый литерал.
Спасибо, учту, в следующей части изменю
Не слушай его, статический массив с строками и цикл по ним с strcmp - ничем не лучше.
Сравнить int гораздо быстрее, чем сравнить строку, поэтому в идеале - enum с значением-индексом к статичному массиву с строками-цветами.
т.е.
enum { COLOR_NONE, ... тыры пыры
COLOR_END
Затем
const char *colors[] = {
"\e[0m",
...
...
NULL
}
Примерно так. Главное чекнуть, что пришедший индекс В диапазоне
COLOR_END <= ind < COLOR_END
Если да - colors[ind].
Строки он в любом случае станет сравнивать т.к. насколько я понимаю это часть парсинга чего-то и просто проиндексировать их enum не выйдет ибо нужно ещё придумать как 0..n замаппить на некоторый хэш от строки. Ну и всякие границы проверять опять же - больше ненужного кода. А так
char* get_color_by_name(const char* color_name) {
struct { char *text, *code; } colors[] = {
{.text="RESET" , .code = RESET },
{.text="BLACK" , .code = BLACK },
{.text="RED" , .code = RED },
{.text="GREEN" , .code = GREEN },
{.text="YELLOW" , .code = YELLOW },
{.text="BLUE" , .code = BLUE },
{.text="MAGENTA", .code = MAGENTA},
{.text="CYAN" , .code = CYAN },
{.text="WHITE" , .code = WHITE },
{.text="GRAY" , .code = GRAY },
};
const int len = sizeof(colors)/sizeof(colors[0]);
for (int i =0; i < len; ++i) {
if (strcmp(color_name, colors[i].text) == 0) {
return colors[i].code;
}
}
return NULL;
}
Маппинги/хардкод отдельно, поиск отдельно ещё и код на четверть короче при ровно той же производительности. Расширять тоже проще - просто добавил строчку в таблицу и готово.
Спасибо, ваш вариант мне понравился. Даже не поленились написать код!
Аналогично следует поступить и с интерпретатором команд - вместо длинной цепочки if/else вставить проверку по массиву и вызов реализующей функции по указателю. Код существенно согратиться, будет более понятен и легко расширяем.
Можно пойти еще чуть дальше - в массив с командами добавить строки с описанием команды (подсказка) и отображать подсказку если команда пришла без требуемых параметров.
Цветовую раскраску следует отключать если работа идет не с интерактивным терминалом.
Статья хороша. спасибо!
обла1дает обширной
А ещё у вас опечатка)
Это статья а не книга.
Зачем здесь "Краткая история С", "Краткие основы C", "Компиляторы: gcc или clang"?
В данном контексте мало того что бесполезно, так еще и вредно:
- размерность базовых типов в стандарте плавающая и указано лишь отношение размерностей. (int >= short, short >= char). Внезапно на некоторых платформах char может оказаться размером 32бита.
- про char лучше думать как о третьем типе на равне с unsigned char, signed char. к какому типу char будет приводится зависит от конкретной реализации компилятора под конкретную платформу. (смотрим описание аргументов к gcc: -funsigned-char, -fsigned-char)
- выбор компилятора зависит от тех условий и других ограничений, а не от "свободная свобода"
- "Для адресов в памяти применяется шестнадцатеричная система." - адрес записанный в память хранится в бинарном виде. 0/1, есть заряд/нет заряда, ... (исключением наверное является компьютер "сетунь", ну и сложные способы хранения информации в современных флеш)
(Могу предположить что... большая часть всей этой информации было содрано с методички препода без понимания того что, в методичке осознано делают упрощения и сокращения, иначе мозг студента будет перегружен)
Для всего остального: что бы вникнуть в основы написания оболочек под linux есть замечательная книга "Linux Application Development, 2ed, Michael K. Johnson, Erik W. Troan", ну или в переводе "Разработка приложений в среде Linux. Программирование для Linux, 2-е издание, Майкл К. Джонсон, Эрик В. Троан"
Насчет методички вы не правы, кратко нашел информацию. А за книги спасибо, почитаю.
А разделы я вставил для того чтобы внести ясность, ну и чтобы заголовок не был кликбейтом.
Благодарю.
Могу предположить что... большая часть всей этой информации было содрано с методички препода без понимания того что, в методичке осознано делают упрощения и сокращения, иначе мозг студента будет перегружен
КМК автор переборщил с использованием нейросети и ему стало жалко вырезать эту воду из статьи. Взгляните на код:
char* read_user_input(void) {
rl_getc_function = getc;
fflush(stdout);
// Буфер ввода (то есть получаем вывод через readline с новой строки с окрашиванием в цвета для красоты)
char* input_buffer = readline("\n\033[2m╰─>\033[0m\033[0;36m $ \033[0m");
Человеку, который знает об указателях на функции и понимает весь этот ребус из приведенного строкового литерала, наверное уже поздно рассказывать про Дениса Ритчи.
Кстати, этот код только приведен только в статье, в репе реализация уже другая.
Про кучу опечаток и странных речевых оборотов я вообще молчу. С самого начала:
И его знать, нет, не обходимо, но довольно желательно.
Я запутался от такого отрицания отрицания.
BINARY_NAME = shegang
А это у китайцев взято, или у чатгпт, который сходил к китайцам?
Для текста я никогда не использую чатгпт, иначе заминисуют
Внезапно на некоторых платформах char может оказаться размером 32бита.
Не может, стандарт гарантирует, что sizeof(char) == 1. Другое дело, что char может оказаться, как знаковым, так и беззнаковым (зависит от архитектуры процессора, ОС и даже версии компилятора). Так что если нужен байт, то лучше взять типы uint8_t
или int8_t
.
Я понимаю, стандарты читать сложно. Возмем к примеру С11 (ISO/IEC 9899:2011)
6.2.5
An object declared as type char is large enough to store any member of the basic execution character set. If a member of the basic execution character set is stored in a char object, its value is guaranteed to be nonnegative. If any other character is stored in a char object, the resulting value is implementation-defined but shall be within the range of values that can be represented in that type.
Тип char должен быть для хранения базового набора символов. Базовый нобор символов описан в секции 5.2.1
3.7.1
character
single-byte character
〈C〉 bit representation that fits in a byte
тоесть char это единичный байт
3.6
byte
addressable unit of data storage large enough to hold any member of the basic character
set of the execution environment
NOTE 1 It is possible to express the address of each individual byte of an object uniquely.
NOTE 2 A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined. The least significant bit is called the low-order bit; the most significant bit is called the high-order bit.
В понимании стандарта byte это последовательность бит количество которых зависит от реализации. Тоесть не обязательно 8бит.
5.2.4.2.1 Sizes of integer types <limits.h>
...
Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.
— number of bits for smallest object that is not a bit-field (byte)
CHAR_BIT 8
Есть файл limits.h в котором будут описаны размеры целочисленных типов в том числе и char. И что эти значения могут быть равными или больше по абсолютному значению представленному в стандарте.
Тоесть char моежет быть 8бит а может и больше. Зависит о конкретной реализации.
Теперь перейдем в пример к конкретной реализации:
Texas Instruments C54x DSPs. Есть gcc и binutils. Процессор специального назначения, оперирует с данными минимальным размеров 16бит в том числе и адресация. здесь char == 16бит.
Во времена создания языка С, байт размерностью в 8 бит не был широко распространет. Существовал целый зоопарк желеха с разной размерностью байта. Я язык перетендовал на широкую переносимость програм. Сейчас в основном попадаются специализированные решения с байтом отличным от 8 бит.
Наверное понимание одного байта.
sizeof(T)
равен некоему размеру в sizeof(char)
, который принят за базу отчёта (единицу) и равен одному байту, размер в битах этой единицы - платформозависимый.
Понравилось про clang лучше gcc) Особенно когда автор слабо понимает различия между двумя этими монстрами и вставил свои пять копеек, потому что шланг "модный", а гцц - легаси, нарушающий стандарты. Так вот вьюноша, сам по себе gcc(как си компайлер) является основой, и стандартом де-факто, сам по себе. Все фишки обкатываются в ядре Линукс и в libc, а потом уже закладываются в стандарт. И гцц тоже кстати, имеет модульную структуру, и ничем особо в этом не отличается от шланга.
// переходим на следующую итерацию если возвращено NULL
if (line == NULL) {
free(line); /* <---------------- !!! */
continue;
}
Надо поправить)) Не ошибка, free прощает NULL, но глаз дернулся))
на начало которого указывает указатель bl
– А почему "bl"?
– Чтобы никто не догадался!
На нейросеть не похоже. Слишком безграмотный русский язык. Тяжело читать.
я наблюдаю за этим автором уже наверно год. Он умудряется иногда генерировать по две получасовые статьи в день! При этом успевает отвечать в коментариях в интонациях школьника.
Я думаю это серьезная группа разработчиков отрабатывает-тренерует машину искуственного интелекта на Хабре, не удивлюсь если это проект внутри Хабра.
Ну хз. Такое чудовищное косноязычие и безграмотность - странный проект получается.
Ну что-ж, господа судебные заседатели, буду развиваться
Была одна статья в которой был сплошной бред про многопоточность, они ее убрали после критики.
я совершенно согласен с вашей оценкой, но в этой конкретной статье хотя бы есть что-то полезное в агрегированной таким образом информации, неужели только за это что-то полезное ее заплюсовали?
Но если это действительно пишет машина то сложно судить хорошо это или плохо, у меня по крайней мере нет таких критериев, а машины тоже надо как-то развивать-тренировать, возможно в этом есть смысл, хотя с внешней, с нашей стороны это действительно выглядит странно, а главное не идет на пользу Хабру, я думаю.
Генерировать по 2 статьи большие в день у меня никак не получалось, да и не вышло бы.
Clang поддерживает все стандарты во всех деталях? Но ведь даже на оф.сайте сказано, что последние стандарты пока только частично, и ещё ладно с C++17, так с C обстоит ещё печальнее.
Программирование на C в Linux на примере создания своей командной оболочки