Ниже приводится два иллюстративных учебных примера.
9.2.1. Учебный пример: генерация кода для ascii– дисплеев
Запущенная без аргументов программа ascii генерирует экран справочной информации по использованию, подобный распечатке, приведенной в примере 9.5.
Данный экран достаточно тщательно спроектирован, чтобы уместиться в 23 строки и 79 колонок, поэтому он помещается в терминальном окне 24×80.
Таблицу можно было бы создавать во время выполнения, т.е. на лету. Подгонка десятичных
и шестнадцатеричных столбцов была бы достаточно простой. Однако существует достаточно необычных, делающих код крайне неудобным, случаев от перенесения строк таблицы в нужных местах до вывода таких неотображаемых символов, как NUL, вместо обычных символов. Более того, столбцы понадобилось бы неравномерно заполнять пробелами, чтобы заставить таблицу уместиться в 79 колонках. Но любой Unix-программист автоматически выражал бы таблицу как блок данных, прежде чем обнаружил бы данные проблемы.
Самым примитивным способом создания справочного экрана было бы помещение каждой строки в C-инициализатор в исходном коде
ascii.с
, а затем заставить код, проходящий через инициализатор, выписывать строки. Проблема такого метода заключается в том, что дополнительные данные в формате C-инициализатора (завершающие разделители строк, строковые кавычки, запятые) удлиняли бы строки более 79 символов. Это привело бы к переносу строк и усложнило бы преобразование внешнего вида кода к внешнему виду вывода, что, в свою очередь, усложнило бы редактирование справочного дисплея, который и без этого сложно было уместить в экран на 24×80 растровых ячеек.
Более сложный метод использования режима вставки строк в препроцессоре ANSI С приводит к другому варианту той же проблемы. По существу, любой способ явного включения в код справочного экрана задействовал бы пунктуацию в начале и конце строки, для которой не было места [94] . А копирование на экран таблицы из файла во время выполнения выглядело ненадежно. В конце концов, файл мог быть утерян.
Пример 9.5. Справка по использованию программы ascii
94
Языки сценариев часто решают данную проблему более изящно, чем С. Для того чтобы понять, как именно они это делают, следует изучить методику потоковых документов (here documents) в shell и конструкцию тройных кавычек в Python.
– e 's/\\/\\\\/g' -e 's/"/\\"/' -e 's/.*/puts("&");/'
Поэтому при сборке программы файл splashscreen автоматически преобразовывается в серию вызовов функции вывода, которые C-препроцессор затем включает в необходимую функцию.
Путем создания кода из данных поддерживается редактируемая версия справочного экрана, идентичного его представлению на дисплее. В результате этого повышается прозрачность. Более того, при желании можно модифицировать справочный экран, не затрагивая C-кода вообще, а верное внешнее представление будет автоматически получено при следующей сборке.
По тем же причинам инициализатор, содержащий строки синонимичных названий, также генерируется посредством sed-сценария в make-файле из файла с именем
nametable
, входящего в состав исходного дистрибутива ascii. Большая часть файла
nametable
просто копируется в С-инициализатор. Но процесс генерации упростил бы адаптацию данного средства для других 8-битовых наборов символов, таких как ISO-8859 (Latin-1 и подобные).