Категории
Самые читаемые
PochitayKnigi » Компьютеры и Интернет » Программное обеспечение » Linux программирование в примерах - Арнольд Роббинс

Linux программирование в примерах - Арнольд Роббинс

Читать онлайн Linux программирование в примерах - Арнольд Роббинс

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 4 5 6 7 8 9 10 11 12 ... 165
Перейти на страницу:

Предпочтительным языком для написания программного обеспечения GNU является С, поскольку это наиболее доступный язык. В мире Unix стандарт С теперь обычен, но если для вас не представляет труда поддержка оригинального С, вы должны сделать это. Хотя стандарты кодирования отдают предпочтение С перед С++, C++ теперь тоже вполне обычен. Примером широко используемого пакета GNU, написанного на С++, является groff (GNU troff). Наш опыт говорит, что с GCC, поддерживающим С++, установка groff не представляет сложности.

Стандарты утверждают, что переносимость является чем-то вроде отвлекающего маневра. Утилиты GNU ясно нацелены на работу с ядром GNU и с библиотекой GNU С[20]. Но поскольку ядро еще не завершено, и пользователи используют инструменты GNU на не-GNU системах, переносимость желательна, но не является первостепенной задачей. Стандарт рекомендует для достижения переносимости между различными системами Unix использовать Autoconf.

1.4.2. Поведение программы

Глава 4 GNU Coding Standards предоставляет общие советы относительно поведения программы. Ниже мы вернемся к одному из ее разделов для более подробного рассмотрения. Глава фокусируется на строении программы, форматировании сообщений об ошибках, написании библиотек (делая их рентабельными) и стандартах для интерфейса командной строки.

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

Утилиты GNU должны использовать для обработки командной строки функцию getopt_long(). Эта функция предусматривает разбор аргументов командной строки как для опций в стиле традиционного Unix ('gawk -F:...'), так и для длинных опций в стиле GNU ('gawk --field-separator=:...'). Все программы должны предусматривать опции --help и --version, а когда в одной программе используется длинное имя, оно таким же образом должно использоваться и в другой программе GNU. Для этой цели есть довольно полный список длинных опций, используемых современными GNU-программами.

В качестве простого, но очевидного примера, --verbose пишется точно таким же способом во всех GNU-программах. Сравните это с -v, -V, -d и т.д. во многих других программах Unix. Большая часть главы 2, «Аргументы, опции и окружение», с. 23, посвящена механике разбора аргументов и опций.

1.4.3. Программирование на С

Наиболее привлекательной частью GNU Coding Standards является глава 5, которая описывает написание кода на С, освещая такие темы, как форматирование кода, правильное использование комментариев, чистое использование С, именование ваших функций и переменных, а также объявление или не объявление стандартных системных функций, которые вы хотите использовать.

Форматирование кода является религиозной проблемой; у многих людей разные стили, которые они предпочитают. Лично нам не нравится стиль FSF, и если вы взглянете на gawk, который мы поддерживаем, вы увидите, что он форматирован в стандартном стиле K&R (стиль расположения кода, использованный в обоих изданиях книги Кернигана и Ричи). Но это единственное отклонение в gawk от этой части стандартов кодирования.

Тем не менее, хотя нам и не нравится стиль FSF[21], мы чувствуем, что при модификации некоторых других программ, придерживание уже использованного стиля кода является исключительно важным. Последовательность в стиле кода более важна, чем сам стиль, который вы выбираете. GNU Coding Standards дает такой же совет. (Иногда невозможно обнаружить последовательный стиль кода, в этом случае программа, возможно, испорчена использованием indent от GNU или cb от Unix.)

Что мы сочли важным в главе о написании кода на С, это то, что эти советы хороши для любого кода на С, а не только когда вы работаете над программой GNU. Поэтому, если вы просто учите С или даже если вы уже работали некоторое время на С (или С++), мы рекомендуем вам эту главу, поскольку она заключает в себе многолетний опыт.

1.4.4. Вещи, которые делают программы GNU лучше

Теперь мы рассмотрим раздел, озаглавленный «Написание надежных программ», в главе 4 «Поведение программ для всех программ». Этот раздел описывает принципы проектирования программного обеспечения, которые делают программы GNU лучше их двойников в Unix Мы процитируем выбранные части главы, с несколькими примерами случаев, в которых эти принципы окупились.

Избегайте произвольных ограничений длины или числа любой структуры данных, включая имена файлов, строки, файлы и символы, выделяя все структуры данных динамически. В большинстве инструментов Unix «длинные строки молча срезаются». Это неприемлемо в инструменте GNU.

Это правило, возможно, единственное наиболее важное в проектировании программного обеспечения GNU — никаких произвольных ограничений. Все инструменты GNU должны быть способны обрабатывать произвольные объемы данных.

Хотя это требование, возможно, усложняет работу программиста, оно облегчает жизнь пользователю. С одной стороны, у нас есть пользователь gawk, регулярно запускающий программу awk для более чем 650 000 файлов (нет, это не опечатка) для сбора статистики, gawk заняла бы более 192 мегабайтов пространства данных, и программа работала бы в течение 7 часов. Он не смог бы запустить эту программу, используя другую реализацию awk.[22]

Утилиты, читающие файлы, не должны удалять символы NUL или любые другие неотображаемые символы, включая символы с кодами больше 0177. Единственными здравыми исключениями были бы утилиты, специально предназначенные для связывания с определенными типами терминалов или принтеров, которые не могут обработать эти символы.

Также хорошо известно, что Emacs может редактировать любые произвольные файлы, включая файлы, содержащие двоичные данные!

По возможности, программы должны обрабатывать должным образом последовательности байтов, представляющих многобайтные символы, используя такие кодировки, как UTF-8 и другие.[23] Каждый системный вызов проверяйте на предмет возвращенной ошибки, если вы не хотите игнорировать ошибки. Включите текст системной ошибки (от perror или эквивалентной функции) в каждое сообщение об ошибке, возникшей при неудачном системном вызове, также, как и имя файла, если он есть, и имя утилиты. Простого «невозможно открыть foo.с» или «ошибка запуска» недостаточно.

Проверка каждого системного вызова создает устойчивость. Это еще один случай, когда жизнь программиста труднее, а пользователя легче. Подробно описанное сообщение об ошибке значительно упрощает нахождение и разрешение проблем[24].

Наконец, мы цитируем главу 1 GNU Coding Standards, которая обсуждает, как написать вашу программу способом, отличным от того, каким написаны программы Unix.

Например, утилиты Unix обычно оптимизированы для минимизации использования памяти, если вы взамен хотите получить скорость, ваша программа будет сильно отличаться. Вы можете хранить весь входной файл в ядре и сканировать его там. вместо использования stdio. Используйте недавно открытый более изящный алгоритм вместо алгоритма Unix-программы. Исключите использование временных файлов. Делайте это в один проход вместо двух (мы сделали это на ассемблере) Или, напротив, сделайте упор на простоте вместо скорости. Для некоторых приложений скорость сегодняшних компьютеров делает адекватными более простые алгоритмы.

Или выберите обобщение. Например, программы Unix часто содержат статичные таблицы или строки фиксированного размера, которые создают произвольные ограничения, используйте вместо этого динамическое выделение памяти. Убедитесь, что ваша программа обрабатывает во входных файлах символы NUL и другие курьезные символы. Добавьте язык программирования для расширяемости и напишите часть программы на этом языке.

Или выделите части программы в независимо используемые библиотеки. Или используйте простой сборщик мусора вместо точного отслеживания, когда освобождать память, или используйте новую возможность GNU, такую как obstacks.

Великолепным примером того, какое отличие можно сделать в алгоритме, является GNU diff. Одним из первых ранних воплощений нашей системы было AT&T 3B1, система с процессором МС68010, огромными двумя мегабайтами памяти и 80 мегабайтами на диске. Мы проделали (и делаем) кучу исправлений в руководстве для gawk, файле длиной почти 28 000 строк (хотя в то время он был лишь в диапазоне 10 000 строк). Обычно мы частенько использовали 'diff -с', чтобы посмотреть на сделанные нами изменения. На этой медленной системе переключение на GNU diff показало ошеломительную разницу во времени появления контекста diff. Разница почти всецело благодаря лучшему алгоритму, который использует GNU diff.

1 ... 4 5 6 7 8 9 10 11 12 ... 165
Перейти на страницу:
Тут вы можете бесплатно читать книгу Linux программирование в примерах - Арнольд Роббинс.
Комментарии