getopt_long(), getopt_long_only()

Разобрать длинные опции, переданные из командной строки

Прототип:

#include <getopt.h>
int getopt_long( int argc,
char * const argv[],
const char *optstring,
const struct option *long_options,
int *idx );
int getopt_long_only( int argc,
char * const argv[],
const char *optstring,
const struct option *long_options,
int *long_idx );
extern char *optarg;
extern int optind, opterr, optopt, optreset;

Аргументы:

argc
Число аргументов, переданных в функцию main().
argv
Массив аргументов, переданных в функцию main().
optstring
Строка символов, идентифицируемых в качестве коротких опций. Если за символом следует символ ":", опция имеет аргумент. Допустимые символы лишь включают буквы и цифры.
long_options
Массив дескрипторов длинных опций, соответствующих struct option. Последний элемент массива должен быть заполнен нулями.
long_idx
Возвращаемый индекс в массиве long_options, характеризующий идентифицированную длинную опцию. Не используется, если передано значение NULL.

Библиотека:

libc

Описание:

Функция getopt_long() идентична getopt() за исключением того, что опции принимаются в двух формах: в виде целых слов или отдельных символов. Таким образом getopt_long() предоставляет расширенный набор функциональности относительно getopt(). Она может быть использована одним из двух способов.

В первом случае каждой длинной опции ставится в соответствие соответствующая короткая, а структура struct option используется только для их связывания. В данном случае getopt_long() функционирует идентично getopt(). Это позволяет достаточно просто привнести поддержку длинных опций в уже существующие программы с минимальными изменениями в коде.

Второй подход подразумевает установку указателя flag в структуре struct option, либо сохранение в структуре указателя на формат аргумента для опций, которые его подразумевают. Дополнительно, аргумент длинной опции может быть указан как опция, включающая знак "=", например:

$ myprogram --myoption=somevalue

Когда длинная опция обнаружена, функция getopt_long() возвращает 0. По этой причине обработка длинных опций по второй схеме не имеет обратной совместимости с getopt(). Комбинирование подходов возможно. Для этого следует связывать длинные опции с короткими лишь для некоторых элементов массива long_options.

Сокращенные (однобуквенные) имена длинных опций обрабатываются автоматически, но только в том случае, когда они уникальны на всем диапазоне записей массива long_options. Всегда предпочтительнее использовать полную форму длинной опции, так как возможны неоднозначные сценарии. Допустим, утилита имеет две опции: $ myprogram --o1-x --o1-y. При ее вызове в форме $ myprogram --o1 в общем случае не известно какая из опций будет обработана. Точный ответ на этот вопрос зависит от порядка следования элементов в массиве long_options.

По умолчанию getopt_long() представляет argv таким образом, что все аргументы опций в командной строке брабатываются перед аргументами, не ассоциированными с опциями. Если первый символ optstring это плюс ("+") или установлена переменная POSIXLY_CORRECT, тогда argv обрабатывается по порядку; процессирование опций останавливается как только встречается первый не ассоциированный с опцией аргумент.

Функция getopt_long_only() работает аналогично getopt_long(), за исключением того, что длинные опции могут иметь префикс либо "-", либо "--". Если опция начинается с "-" и не соответствует ни одной длинной опции, но соответствует короткой - используется последняя.

Особенности реализации:

Данный раздел приводит сравнение GNU реализации функции и данной (соответствует BSD):

Возвращаемое значение:

Переменные окружения:

POSIXLY_CORRECT
Если переменная установлена, обработка опций прекращается при обнаружении первой конструкции не являющейся опцией. Предваряющий символ "+" в optstring игнорируется.

Примеры:

int bflag, ch, fd;
int daggerset;
/* options descriptor */
static struct option longopts[] = {
{ "buffy", no_argument, NULL, 'b' },
{ "fluoride", required_argument, NULL, 'f' },
{ "daggerset", no_argument, &daggerset, 1 },
{ NULL, 0, NULL, 0 }
};
bflag = 0;
while ( (ch = getopt_long( argc, argv, "bf:", longopts, NULL )) != -1 )
switch ( ch )
{
case 'b':
bflag = 1;
break;
case 'f':
if ( (fd = open( optarg, O_RDONLY, 0 )) == -1 )
err( 1, "unable to open %s", optarg );
break;
case 0:
if ( daggerset )
fprintf( stderr, "Buffy will use her dagger to apply fluoride to dracula's teeth\n" );
break;
default:
usage();
}
argc -= optind;
argv += optind;

Классификация:

BSD, GNU

Поддерживается, начиная с ЗОСРВ «Нейтрино» редакции 2018

Точка остановки потока
Нет
Обработчик прерываний
Нет
Обработчик сигналов
Нет
В потоке
Нет

Тематические ссылки:

struct option, getopt()




Предыдущий раздел: Описание API системной библиотеки