Иногда программы предлагают параметры, которые, возможно, не должны использоваться; они могут быть включены для поддержки унаследованных приложений или приложений, разработанных только для тестирования. Автоматическая генерация справочных сообщений для такого параметра можно подавить с помощью битового "ИЛИ"
POPT_ARGFLAG_DOC_HIDDEN
и члена
arg
структуры
struct poptOption
, описывающей данный параметр.
26.3. Использование обратных вызовов
Мы показали два способа обработки параметров с помощью библиотеки
popt
: с помощью возврата параметра функцией
poptGetNextOpt
и путем автоматического изменения переменных во время представления параметров. К сожалению, ни один из этих способов не подходит для вложенных таблиц. Очевидно, что возвращение параметров, определяемых во вложенной таблице для обработки в приложении, не будет работать, поскольку вложенные таблицы предназначены для того, чтобы приложению не нужно было знать, какие параметры предлагает библиотека. Присвоение переменным значений тоже не подходит, поскольку в этом случае не ясно, каким переменным нужно присваивать значения. Использование глобальных переменных часто тоже является неподходящим, а библиотека не имеет доступных для использования локальных переменных, поскольку синтаксический анализ выполняется из главного приложения, а не из библиотеки. Чтобы обеспечить гибкую обработку параметров во вложенных таблицах, библиотека
popt
предлагает использовать обратные вызовы (callback).
Каждая таблица может определять свою собственную функцию обратного вызова, которая подменяет обычную обработку параметров, определенных в этой таблице. Вместо нее функция обратного вызова вызывается для каждого обнаруживаемого параметра. Параметры, определяемые в других таблицах параметров (включая таблицы, вложенные в таблицу, определяющую обратный вызов), обрабатываются с использованием обычных правил, если только в других таблицах не будут определены свои собственные обратные вызовы.
Обратные вызовы можно определять только в первом элементе таблицы параметров. Если этот элемент определяет обратный вызов, член
argInfo
будет иметь значение
POPT_ARG_CALLBACK
, a
arg
будет указывать на функцию обратного вызова. Член
descrip
может представлять любое значение указателя, и передается в обратный вызов каждый раз во время его инициирования, открывая доступ к любым произвольным данным. Все остальные члены структуры
struct poptOption
должны иметь нулевое значение или
NULL
.
Во время обработки параметров обратный вызов можно инициировать в трех точках: до начала обработки, при нахождении параметра в таблице для данного обратного вызова и после завершения обработки. Это дает библиотекам возможность инициализировать любые необходимые им структуры (включая данные, определяемые членом
descrip
), и выполнять любые служебные действия, которые могут понадобиться после завершения обработки (например, очищать динамическую память, выделенную для члена
descrip
). Они всегда вызываются при нахождении параметра, однако в таблице параметров необходимо указать, что их нужно вызывать в двух других местах. Чтобы сделать это, значения
POPT_CBFLAG_PRE
или
POPT_CBFLAG_POST
(или оба) должны объединяться битовым "ИЛИ" со значением
POPT_ARG_CALLBACK
, присвоенным члену
arg
структуры, которая определяет обратный вызов.
Далее показан прототип, который следует использовать для определения функции обратного вызова:
Первый параметр представляет содержимое, синтаксический анализ которого будет выполнен во время инициирования обратного вызова. Следующим параметров является
POPT_CALLBACK_REASON_PRE
, если обработка параметра еще не началась,
POPT_CALLBACK_REASON_POST
,
если обработка параметров завершена, или
POPT_CALLBACK_REASON_OPTION
, если в таблице для данного обратного вызова был обнаружен параметр. Если этот параметр является последним, то аргумент opt будет указывать на элемент таблицы параметров для обнаруженного параметра, а аргумент
arg
будет указывать на строку, определяющую аргумент для данного параметра. Если ожидается аргумент, не представленный в виде строки, обратный вызов будет отвечать за проверку типа и преобразование аргумента. Последний параметр для обратного вызова,
data
, представляет собой значение поля
descrip
в элементе таблицы параметров, который задает обратный вызов.
Ниже показан пример библиотеки, которая использует вложенную таблицу
popt
и обратные вызовы для синтаксического анализа некоторых параметров командной строки. Структура данных инициализируется до начала синтаксического анализа командной строки, а затем отображаются последние значения.
1: /* popt-lib.с */
2:
3: #include <popt.h>
4: #include <stdlib.h>
5:
6: struct params {
7: int height, width;
8: char*fg,*bg;
9: };
10:
11: static void callback(poptContext con,
12: enum poptCallbackReason reason,
13: const struct poptOption * opt,
14: const char * arg,
15: const void * data);
16:
17: /* Здесь сохраняются переменные, которые прошли синтаксический анализ. Обычно
18: глобальные переменные использовать не рекомендуется, зато работать с ними проще.*/