Linux программирование в примерах
Часть 20 из 253 Информация о книге
104 {"ignore-environment", no_argument, NULL, 'i'},105 {"unset", required_argument, NULL, 'u'},106 {GETOPT_HELP_OPTION_DECL},107 {GETOPT_VERSION_OPTION_DECL},108 {NULL, 0, NULL, 0}109 };GNU Coreutils содержит большое число программ, многие из которых выполняют одни и те же общие задачи (например, анализ аргументов). Для облегчения сопровождения многие типичные идиомы были определены в виде макросов. Двумя таким макросами являются
иGETOPT_HELP_OPTION_DECL(строки 106 и 107). Вскоре мы рассмотрим их определения. Первая функция,GETOPT_VERSION_OPTION, выводит информацию об использовании и завершает программу. Макросusage()(строка 115, используется также по всей программе) также предназначен для локализации, пока также считайте его содержащим строковую константу._("string")111 void112 usage(int status)113 {114 if (status '= 0)115 fprintf(stderr, _("Try '%s --help' for more information.\n"),116 program_name);117 else118 {119 printf (_("\120 Usage: %s [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]\n"),121 program_name);122 fputs (_("\123 Set each NAME to VALUE in the environment and run COMMAND. \n\124 \n\125 -i, --ignore-environment start with an empty environment\n\126 -u, --unset=NAME remove variable from the environment\n\127 "), stdout);128 fputs(HELP_OPTION_DESCRIPTION, stdout);129 fputs(VERSION_OPTION_DESCRIPTION, stdout);130 fputs(_("\131 \n\132 A mere - implies -i. If no COMMAND, print the resulting\133 environment.\n"), stdout);134 printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);135 }136 exit(status);137 }Первая часть
объявляет переменные и настраивает локализацию. Функцииmain(),setlocale()иbindtextdomain()(строки 147–149) обсуждаются в главе 13 «Интернационализация и локализация». Отметим, что эта программа использует аргументtextdomain()(строка 140). Это единственная программа Coreutils, которая так делает. Наконец, вызовmain() envpв строке 151 (см. раздел 9.1.5.3. «Функции завершения») регистрирует библиотечную функцию Coreutils, которая очищает все выходные буферы и закрываетatexit(), выдавая сообщение при ошибке. Следующая часть программы обрабатывает аргументы командной строки, используяstdout.getopt_long()139 int140 main(register int argc, register char **argv, char **envp)141 {142 char *dummy_environ[1];143 int optc;144 int ignore_environment = 0;145146 program_name = argv[0];147 setlocale(LC_ALL, "");148 bindtextdomain(PACKAGE, LOCALEDIR);149 textdomain(PACKAGE);150151 atexit(close_stdout);152153 while ((optc = getopt_long(argc, argv, "+iu:", longopts, NULL)) != -1)154 {155 switch (optc)156 {157 case 0:158 break;159 case 'i':160 ignore_environment = 1;161 break;162 case 'u':163 break;164 case_GETOPT_HELP_CHAR;165 case_GETOPT_VERSION_CHAR(PROGRAM_NAME, AUTHORS);166 default:167 usage(2);168 }169 }170171 if (optind != argc && !strcmp(argv[optind], "-"))172 ignore_environment = 1;Вот отрывок из файла
в дистрибутиве Coreutils с упомянутыми ранее определениями и макросом 'src/sys2.h', использованным выше (строки 164–165):case_GETOPT_xxx/* Вынесение за скобки общей части кода, обрабатывающего --help и--version. *//* Эти значения перечисления никак не могут конфликтовать со значениями опций,обычно используемыми командами, включая CHAR_MAX + 1 и т.д. ИзбегайтеCHAR_MIN - 1, т.к. оно может равняться -1, значение завершения опций getopt.*/enum {GETOPT_HELP_CHAR = (CHAR_MIN — 2),GETOPT_VERSION_CHAR = (CHAR_MIN - 3)};