командного процессора.
ФУНКЦИЯ
Печатает начальные строки комментария к командному файлу командно-
го процессора, что выражено буквой "s" в имени. Первая строка игнориру-
ется для совместимости с командным процессором языка Си.
ФОРМАТ
strips файл [...]
ПРИМЕР ВЫЗОВА
strips *.sh
Извлекает комментарии из всех командных файлов в текущем каталоге.
ИСХОДНЫЙ КОД ДЛЯ strips
1 :
2 # @(#) strips v1.0 Strip shell comment header
Author: Russ Sage
4 for FILE in $@
5 do
6 cat $FILE | (read LINE; echo $LINE
7 while read LINE
8 do
9 if [ "`echo $LINE|cut -c1`" = "#" ]
10 then echo "$LINE"
11 else exit
12 fi
13 done)
14 done
ПЕРЕМЕННЫЕ СРЕДЫ
FILE Хранит каждое имя файла, полученное из
командной строки.
LINE Хранит каждую строку вводного текста,
полученную из читаемого файла.
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН strips?
Так же как нам нужны средства обработки документации для файлов с
исходным кодом на Си, нам нужны и аналогичные средства для командных
файлов командного процессора. Разница между извлечением комментариев из
кода на языке Си и их извлечением из кода командных файлов командного
процессора - в способе разграничения комментариев в исходном файле.
Исходный файл на Си использует пару /* */, а командные файлы командного
процессора применяют #, чтобы выделить остаток строки как комментарий.
Обработка документации облегчается, когда командные файлы следуют
некоторой форме стандартизованной документации. В действительности нет
формального стандарта, но наиболее близкий стандарт приходит со страниц
руководств по самой системе UNIX. Стандартными полями являются имя ко-
мандного файла, способ его вызова, что он делает и, возможно, некоторые
пометки о том, как он работает, ссылки на другие места для поиска ин-
формации и сведения о том, какие файлы использует данный командный
файл. Пример формата выглядит так:
:
# ИМЯ
# strips Извлекает поля shell-комментариев
#
# ФОРМАТ ВЫЗОВА
# strips файл [...]
#
# АВТОР
# Russ Sage mm/dd/yy
#
# ОПИСАНИЕ
# Данный командный файл извлекает комментирующие
# заголовки из командных файлов интерпретатора shell.
#
# СМ. ТАКЖЕ
# sh(1), cat(1)
Отметим, что в первой строке имеется оператор :, который является
для командного процессора нулевым оператором. Он ничего не делает, но
всегда возвращает успешный статус выхода. Он находится в отдельной
строке, поскольку это обозначает командный файл для Bourne shell. Если
вы запускаете /bin/csh вместо /bin/sh, командные файлы могут вызвать
путаницу. C Shell ищет символ # в первой колонке первой строки. Если он
там есть, командный процессор считает этот файл командным файлом ин-
терпретатора csh. Чтобы указать интерпретатору csh, что командный файл
предназначен для интерпретатора Bourne shell, мы можем оставить эту
строку пустой (что будет не слишком хорошо печататься и подлежит удале-
нию) или поместить оператор, который сообщает интерпретатору C Shell,
что это командный файл для Bourne shell, но ничего не делает под управ-
лением Bourne shell.
ЧТО ДЕЛАЕТ strips?
Strips читает командный файл и печатает все комментарии с начала
файла, которые являются непрерывными (т.е. печатает, пока не достигнет
строки, не являющейся комментарием). Первая строка игнорируется, но пе-
чатается. Когда строка не имеет символа # в первой символьной позиции,
strips прекращает чтение этого файла.
Командный файл должен иметь структуру комментария, аналогичную
структуре, показанной в нашем предыдущем примере. Символы # должны быть
в первой позиции, и каждая строка должна иметь символ #. Если у вас
есть пустая строка где-нибудь в начальном блоке комментариев, strips
печатает только первую часть блока.
ПРИМЕРЫ
1. $ strips `kind /bin /usr/bin`
Блоки комментариев извлекаются из текстовых файлов, размещенных в
каталогах /bin и /usr/bin.
2. $ find / -name "*.sh" -print | while read FILE
> do
> strips $FILE > /tmp/doc/$FILE
> done
Find порождает список всех имен файлов, который попадает в strips.
Выход strips направляется в каталог документации в /tmp. Окончательный
выход попадает в файл с точно таким же именем, как исходный файл, толь-
ко выход помещается в /tmp, поэтому никаких случайных удалений не про-
исходит.
ПОЯСНЕНИЯ
Строки 4 и 14 окаймляют внешний цикл, который подает имена файлов
данному командному файлу. Обработки или проверки ошибок нет. Пока в ко-
мандной строке есть файлы, цикл продолжается. Вы можете, конечно, про-
верить наличие аргументов, правильность и существование файлов. Для
этого, мы думаем, вы видели достаточно примеров проверки ошибок, чтобы
добавить их, куда вам нужно. Поэтому мы иногда опускаем такие фрагменты
в нашем коде, чтобы сэкономить место и выделить главную функцию.
Строка 6 применяет команду cat к файлу, который сейчас обрабатыва-
ется. Выход направляется в конвейер, чтобы его прочитал другой shell.
Новый shell получает длинную командную строку (обозначенную скобками в
строках 6 и 13). Первая команда read читает самую первую строку.
Поскольку мы не собираемся проверять эту строку, мы отображаем ее, а
затем опускаемся в цикл последовательного чтения. Предполагается, что
первая строка начинается с двоеточия, но если она начинается с символа
#, она все равно печатается, так что вы не будете терять текст.
Строки 7-13 являются внутренним циклом while, читающим строки
текста со стандартного ввода, который был выходом команды cat. Когда
текст заканчивается, прекращается и цикл while.
Строки 9-12 - это строки принятия решения. Сначала мы отображаем
текущую вводную строку и передаем ее по конвейеру команде cut. Выреза-
ется первый символ, затем команда сравнения проверяет, совпадает ли он
с символом комментария. Если да, строка отображается на стандартный вы-
вод. Если это не символ комментария, то нужно достичь конца блока ком-
ментариев, поэтому происходит выход из внутреннего цикла. Управление
возвращается во внешний цикл (for), который стартует и берет следующее
имя файла. Когда все файлы обработаны, strips завершается.
4.3. ctags - создание файла признаков исходного кода проекта
---------------------------------------------------------------------------
ИМЯ: ctags
---------------------------------------------------------------------------
ctags Делает файл признаков исходного кода для
простоты доступа с помощью утилиты vi.
ФОРМАТ
ctags [файл ...]
ПРИМЕР ВЫЗОВА
ctags proj*.c
Делает файл признаков для всего исходного кода проекта.
ИСХОДНЫЙ КОД ДЛЯ ctags
1 :
2 # @(#) ctags v1.0 Create a C source code tag file
Author: Russ Sage
4 awk -F'(' '/^[a-zA-Z_][a-zA-Z0-9_]*\(/ {
5 printf ("%s\t%s\t/^%s$/\n", $1, FILENAME, $0) }'
$@ | sort -u +0 -1
ПЕРЕМЕННАЯ СРЕДЫ
FILENAME awk Переменная, содержащая имя файла.
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН ctags?
UNIX создан как среда для разработки программного обеспечения. Она
поддерживает и поощряет модульность исходного кода программы. Модуль-
ность - это концепция разбиения проекта на отдельные файлы, превращения
идей в подпрограммы и компиляции отдельных файлов с исходным кодом в
перемещаемые модули для последующей их сборки в исполняемый модуль.
Такая философия разработки программного обеспечения может, однако,
породить некоторые проблемы. Главная проблема - попытка получить неко-
торого рода сцепку из всех маленьких кусков головоломки. Делаются вызо-
вы подпрограмм, которые находятся в других файлах, возможно даже в дру-
гих каталогах. Нужен инструмент, позволяющий нам, людям, посмотреть на
программное обеспечение человеческим взглядом, т.е. содержательно, а не
с точки зрения физического размещения. Этот подход чем-то аналогичен
чтению книги в сравнении с чтением компьютерной распечатки. Распечатка
заставляет вас делать последовательный просмотр, а книга допускает пря-
мой доступ (и обычно предоставляет оглавление и предметный указатель
для поиска специфических пунктов).
Ctags преодолевает этот разрыв, создавая файл специального форма-
та, который распознают редакторы vi и ex. Этот файл содержит "призна-
ки", которые могут быть использованы при работе с редактором для
обеспечения автоматического доступа к любой нужной функции, не требую-
щего от вас знаний о том, в каком файле находится функция.
Фактически, ctags предоставляет вам предметный указатель для груп-
пы файлов с исходным кодом на языке Си. Когда вы объединяете его с ре-
дактором, вы можете быстро найти любую функцию по известному вам имени
и посмотреть тело функции. Это значит также, что вы можете легко копи-
ровать и вставлять функции в любой исходный файл, с которым вы сейчас
работаете.
Если редактор не имел возможности работы с признаками или мы не
построили инструментальное средство, использующее такое преимущество,
то мы должны запускать grep для имени функции на наборе исходных файлов
на Си (в надежде, что у нас есть подходящие файлы!), отмечать, какой
файл имеет требуемую функцию, входить в этот файл редактором (вручную
вводя все символы имени файла), а затем набирать символы шаблона по-
иска. Это большая работа, которая может занять много времени. Благодаря
использованию возможности работы с признаками, для файла признаков, из-
влеченных из исходного кода, вся эта ручная работа сокращается.
Это сочетание возможностей иллюстрирует то, чему не часто прида-
ется значение: владельцы UNIX всегда настороженно относятся к возмож-
ности использовать преимущества многочисленных средств, уже имеющихся в
таких программах, как vi или ex. Зачастую от 90 до 95 процентов необхо-
димых вам возможностей уже имеются, ожидая относительно простого ко-
мандного файла интерпретатора shell, связывающего их вместе в мощный
новый инструмент.
Ctags уже существует в виде исполняемого модуля в системе Berkely
(BSD) и в нынешней AT&T System V. Он происходит из системы Berkely, но
поддерживается теперь в System V. Это иллюстрация взаимодействия между
этими двумя источниками в мире UNIX, поскольку они взаимствуют полезные
идеи друг у друга. Данное конкретное воплощение ctags является команд-
ным файлом утилиты awk, имитирующим исполняемую программу из системы
Berkely, а это значит, что пользователи систем XENIX и предыдущих
версий AT&T могут теперь извлечь пользу от применения ctags. Еще одно