Linux программирование в примерах | страница 46



, выдавая сообщение при ошибке. Следующая часть программы обрабатывает аргументы командной строки, используя >getopt_long().

>139 int

>140 main(register int argc, register char **argv, char **envp)

>141 {

>142  char *dummy_environ[1];

>143  int optc;

>144  int ignore_environment = 0;

>145

>146  program_name = argv[0];

>147  setlocale(LC_ALL, "");

>148  bindtextdomain(PACKAGE, LOCALEDIR);

>149  textdomain(PACKAGE);

>150

>151  atexit(close_stdout);

>152

>153  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  }

>170

>171  if (optind != argc && !strcmp(argv[optind], "-"))

>172   ignore_environment = 1;

Вот отрывок из файла >src/sys2.h в дистрибутиве Coreutils с упомянутыми ранее определениями и макросом '>case_GETOPT_xxx', использованным выше (строки 164–165):

>/* Вынесение за скобки общей части кода, обрабатывающего --help и

>   --version. */

>/* Эти значения перечисления никак не могут конфликтовать со значениями опций,

>   обычно используемыми командами, включая CHAR_MAX + 1 и т.д. Избегайте

>   CHAR_MIN - 1, т.к. оно может равняться -1, значение завершения опций getopt.

>*/

>enum {

> GETOPT_HELP_CHAR = (CHAR_MIN — 2),

> GETOPT_VERSION_CHAR = (CHAR_MIN - 3)

>};

>#define GETOPT_HELP_OPTION_DECL \

> "help", no_argument, 0, GETOPT_HELP_CHAR

>#define GETOPT_VERSION_OPTION_DECL \

> "version", no_argument, 0, GETOPT_VERSION_CHAR

>#define case_GETOPT_HELP_CHAR \

> case GETOPT_HELP_CHAR: \

>  usage(EXIT_SUCCESS); \

>  break;

>#define case_GETOPT_VERSION_CHAR(Program_name, Authors) \

> case GETOPT_VERSION_CHAR: \

>  version_etc(stdout, Program_name, PACKAGE, VERSION, Authors); \

>  exit(EXIT_SUCCESS); \

>  break;

Результатом этого кода является печать сообщения об использовании утилиты для >--help и печать информации о версии для >--version. Обе опции завершаются успешно («Успешный» и «неудачный» статусы завершения описаны в разделе 9.1.5.1 «Определение статуса завершения процесса».) Поскольку в Coreutils входят десятки утилит, имеет смысл вынести за скобки и стандартизовать как можно больше повторяющегося кода.

Возвращаясь к >env.с:

>174 environ = dummy_environ;

>175 environ[0] = NULL;

>176

>177 if (!ignore_environment)

>178  for (; *envp; envp++)

>179   putenv(*envp);

>180

>181 optind = 0; /* Принудительная реинициализация GNU getopt. */