diff --git a/content/posts/2022/openbsd-indent-on-linux.md b/content/posts/2022/openbsd-indent-on-linux.md new file mode 100644 index 0000000..2c306c5 --- /dev/null +++ b/content/posts/2022/openbsd-indent-on-linux.md @@ -0,0 +1,108 @@ +--- +title: "indent из OpenBSD в Linux" +date: 2022-10-06T16:06:13+03:00 +draft: false +tags: [c, linux, openbsd] +--- + +## О утилите + +[indent.1](https://man.openbsd.org/indent.1) — +unix утилита для исправления отступов +и форматирования исходного кода программ на Си. + +**Справочный материал:** +[OpenBSD manual page](https://man.openbsd.org/indent.1) +[Indent_(Unix) _Wikipedia_](https://en.wikipedia.org/wiki/Indent_(Unix)) + +Эта утилита своеобразный **code beautifier** для Си. + +## GNU реализации + +В Linux существует [GNU Indent](https://www.gnu.org/software/indent/manual/), +код доступен на серверах **savannah.gnu.org**: + +```sh +git clone https://git.savannah.gnu.org/git/indent.git +``` + +Версия 2.2.12 вышла 18 апреля 2021 года. + +Но ведь этоже GNU, бее. + +## OpenBSD реализация + +В OpenBSD есть своя версия. Издавно известно, что разработчики OpenBSD +_они пишут лучший C код в мире_ [[1](https://www.opennet.ru/openforum/vsluhforumID3/128533.html#57)]. + +Исходный код доступен по следующей ссылке: + +```text +https://github.com/openbsd/src/tree/master/usr.bin/indent +``` + +Однако собрать его не получится, без некоторых изменений :) + +## Код + +Я клонировал исходный код на свой Git сервер и сделал изменений, +которые позволяют собрать библиотеку в Linux. + +Коммит с изменениями доступен по +[этой ссылке](https://git.a2s.su/iiiypuk/indent/commit/a250dd83d47981cf6ed9a4382aae120a7fb24468). + +Изменения коснулись следующих файлов: + +* Makefile +* args.c +* indent.c +* lexi.c + +В файле `Makefile` я закоментировал строку с инклудом параметром для сборки OpenBSD. + +```text +.include +``` + +В файле `indent.c` убрал механизм безопасности OpenBSD +[Pledge](https://man.openbsd.org/pledge.2). + +Оригинальный код: + +```c +if (pledge("stdio rpath wpath cpath", NULL) == -1) + err(1, "pledge"); +``` + +Мои правки: + +```text +#if defined(__linux__) + // +#else + if (pledge("stdio rpath wpath cpath", NULL) == -1) + err(1, "pledge"); +#endif +``` + +В файлах `args.c` и `indent.c` я сколхозил, заменив OpenBSD специфичные функции +`errc` и `warnc` на функцию `printf`. + +По хорошему нужно изучить работу функций, похоже что они возвращают ещё код ошибки, +но на текущий момент и так сойдёт. + +В файле `lexi.c` заменил функцию `strlcpy` на `strncpy`: + +```diff +- strlcpy(ps.procname, token, sizeof ps.procname); ++ strncpy(ps.procname, token, sizeof ps.procname); +``` + +Работют они конечно по разному, но ничего сломаться в штатной обстановке не должно. + +## Итог + +По факту код оказался полностью кросс-платформенным, +за исключением нескольных моментов. + +Бинарных сборок нет, собирайте сами!