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: глобальные переменные использовать не рекомендуется, зато работать с ними проще.*/
19: struct params ourParam;
20:
21: struct poptOption libTable[] = {
22: { NULL, ' ',
23: POPT_ARG_CALLBACK | POPT_CBFLAG_PRE | POPT_CBFLAG_POST,
24: callback, ' ', (void *) &ourParam, NULL },
25: { 'height', 'h', POPT_ARG_STRING, NULL, ' ', NULL, NULL },
26: { 'width', 'w', POPT_ARG_STRING, NULL, ' ', NULL, NULL },
27: { 'fg', 'f', POPT_ARG_STRING, NULL, ' ', NULL, NULL },
28: { 'bg', 'b', POPT_ARG_STRING, NULL, ' ', NULL, NULL },
29: { NULL, ' ', POPT_ARG_NONE, NULL, ' ', NULL, NULL }
30: };
31:
32: static void callback(poptContext con,
33: enum poptCallbackReason reason,
34: const struct poptOption * opt,
35: const char * arg,
36: const void * data) {
37: struct params * p = (void *) data;
38: char * chptr = NULL;
39:
40: if (reason == POPT_CALLBACK_REASON_PRE) {
41: p->height = 640;
42: p->width = 480;
43: p->fg = 'white';
44: p->bg = 'black';
45: } else if (reason == POPT_CALLBACK_REASON_POST) {
46: printf('используется высота %d ширина %d передний план %s фон %s
',
47: p->height, p->width, p->fg, p->bg);
48:
49: } else {
50: switch (opt->shortName) {
51: case 'h': p->height = strtol(arg, &chptr, 10); break;
52: case 'w': p->width = strtol(arg, &chptr, 10); break;
53: case 'f' : p->fg = (char *) arg; break;
54: case 'b': p->bg = (char *) arg; break;
55: }
56:
57: if (chptr && *chptr) {
58: fprintf(stderr, 'для %s ожидался числовой аргумент
',
59: opt->longName);
60: exit(1);
61: }
62: }
63: }
64:
Программа, для которой необходимо обеспечить эти аргументы командной строки, должна включать одну дополнительную строку в своей таблице popt
. Обычно этой строкой является макрос, задаваемый в заголовочном файле (подобно тому, как реализуется POPT_AUTOHELP
), но в целях упрощения в данном примере мы просто явным образом покажем эту строку.
1: /* popt-nest.c */
2:
3: #include <popt.h>
4:
5: /* Обычно это объявление осуществляется в заголовочном файле */
6: extern struct poptOption libTable[];
7:
8: int main(int argc, const char * argv[]) {
9: poptContext optCon;
10: int rc;
11: struct poptOption options[] = {
12: { 'app1', ' ', POPT_ARG_NONE, NULL, ' ' },
13: { NULL, ' ', POPT_ARG_INCLUDE_TABLE, libTable,
14: ' ', 'Nested:', }
15: POPT_AUTOHELP
16: { NULL, ' ', POPT_ARG_NONE, NULL, ' ' }
17: };
18:
19: optCon = poptGetContext('popt-nest', argc, argv, options, 0);
20:
21: if ((rc = poptGetNextOpt (optCon)) < -1) {
22: fprintf(stderr, '%s: %s
',
23: poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
24: poptStrerror(rc));
25: return 1;
26: }
27:
28: return 0;
29: }
26.4. Обработка ошибок
Каждая из функций popt
, которая может возвращать ошибки, возвращает целочисленные значения. В случае возникновения ошибки возвращается отрицательный код. В табл. 26.2 перечислены коды возможных ошибок. После таблицы дается подробное обсуждение каждой ошибки.