1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3 /* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
4 file accompanying popt source distributions, available from
5 ftp://ftp.redhat.com/pub/code/popt */
12 static void displayArgs(poptContext con, enum poptCallbackReason foo,
13 struct poptOption * key,
14 const char * arg, void * data) {
15 if (key->shortName== '?')
16 poptPrintHelp(con, stdout, 0);
18 poptPrintUsage(con, stdout, 0);
22 struct poptOption poptHelpOptions[] = {
23 { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL },
24 { "help", '?', 0, NULL, '?', "Show this help message" },
25 { "usage", '\0', 0, NULL, 'u', "Display brief usage message" },
26 { NULL, '\0', 0, NULL, 0 }
31 getTableTranslationDomain(const struct poptOption *table)
33 const struct poptOption *opt;
36 opt->longName || opt->shortName || opt->arg;
38 if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
45 static const char * getArgDescrip(const struct poptOption * opt,
46 const char *translation_domain) {
47 if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
49 if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
50 if (opt->argDescrip) return POPT_(opt->argDescrip);
52 if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
56 static void singleOptionHelp(FILE * f, int maxLeftCol,
57 const struct poptOption * opt,
58 const char *translation_domain) {
59 int indentLength = maxLeftCol + 5;
60 int lineLength = 79 - indentLength;
61 const char * help = D_(translation_domain, opt->descrip);
65 char * left = malloc(maxLeftCol + 1);
66 const char * argDescrip = getArgDescrip(opt, translation_domain);
69 if (opt->longName && opt->shortName)
70 sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
71 else if (opt->shortName)
72 sprintf(left, "-%c", opt->shortName);
73 else if (opt->longName)
74 sprintf(left, "--%s", opt->longName);
81 strcat(left, argDescrip);
85 fprintf(f," %-*s ", maxLeftCol, left);
87 fprintf(f," %s\n", left);
94 helpLength = strlen(help);
95 while (helpLength > lineLength) {
96 ch = help + lineLength - 1;
97 while (ch > help && !isspace(*ch)) ch--;
98 if (ch == help) break; /* give up */
99 while (ch > (help + 1) && isspace(*ch)) ch--;
102 sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
103 fprintf(f, format, help, " ");
105 while (isspace(*help) && *help) help++;
106 helpLength = strlen(help);
109 if (helpLength) fprintf(f, "%s\n", help);
112 static int maxArgWidth(const struct poptOption * opt,
113 const char * translation_domain) {
118 while (opt->longName || opt->shortName || opt->arg) {
119 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
120 this = maxArgWidth(opt->arg, translation_domain);
121 if (this > max) max = this;
122 } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
123 this = opt->shortName ? 2 : 0;
126 this += strlen(opt->longName) + 2;
129 s = getArgDescrip(opt, translation_domain);
131 this += strlen(s) + 1;
132 if (this > max) max = this;
141 static void singleTableHelp(FILE * f, const struct poptOption * table,
143 const char *translation_domain) {
144 const struct poptOption * opt;
145 const char *sub_transdom;
148 while (opt->longName || opt->shortName || opt->arg) {
149 if ((opt->longName || opt->shortName) &&
150 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
151 singleOptionHelp(f, left, opt, translation_domain);
156 while (opt->longName || opt->shortName || opt->arg) {
157 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
158 sub_transdom = getTableTranslationDomain(opt->arg);
160 sub_transdom = translation_domain;
163 fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
165 singleTableHelp(f, opt->arg, left, sub_transdom);
171 static int showHelpIntro(poptContext con, FILE * f) {
175 fprintf(f, POPT_("Usage:"));
176 if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
177 fn = con->optionStack->argv[0];
178 if (strchr(fn, '/')) fn = strchr(fn, '/') + 1;
179 fprintf(f, " %s", fn);
180 len += strlen(fn) + 1;
186 void poptPrintHelp(poptContext con, FILE * f, int flags) {
189 showHelpIntro(con, f);
191 fprintf(f, " %s\n", con->otherHelp);
193 fprintf(f, " %s\n", POPT_("[OPTION...]"));
195 leftColWidth = maxArgWidth(con->options, NULL);
196 singleTableHelp(f, con->options, leftColWidth, NULL);
199 static int singleOptionUsage(FILE * f, int cursor,
200 const struct poptOption * opt,
201 const char *translation_domain) {
204 const char * item = shortStr;
205 const char * argDescrip = getArgDescrip(opt, translation_domain);
207 if (opt->shortName) {
208 if (!(opt->argInfo & POPT_ARG_MASK))
209 return cursor; /* we did these already */
211 *shortStr = opt->shortName;
213 } else if (opt->longName) {
214 len += 1 + strlen(opt->longName);
215 item = opt->longName;
218 if (len == 3) return cursor;
221 len += strlen(argDescrip) + 1;
223 if ((cursor + len) > 79) {
228 fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item,
229 argDescrip ? (opt->shortName ? " " : "=") : "",
230 argDescrip ? argDescrip : "");
232 return cursor + len + 1;
235 static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
236 const char *translation_domain) {
237 const struct poptOption * opt;
240 while (opt->longName || opt->shortName || opt->arg) {
241 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN)
242 translation_domain = (const char *)opt->arg;
243 else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
244 cursor = singleTableUsage(f, cursor, opt->arg,
246 else if ((opt->longName || opt->shortName) &&
247 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
248 cursor = singleOptionUsage(f, cursor, opt, translation_domain);
256 static int showShortOptions(const struct poptOption * opt, FILE * f,
258 char s[300]; /* this is larger then the ascii set, so
259 it should do just fine */
263 memset(str, 0, sizeof(s));
266 while (opt->longName || opt->shortName || opt->arg) {
267 if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
268 str[strlen(str)] = opt->shortName;
269 else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
270 showShortOptions(opt->arg, f, str);
278 fprintf(f, " [-%s]", s);
279 return strlen(s) + 4;
282 void poptPrintUsage(poptContext con, FILE * f, int flags) {
285 cursor = showHelpIntro(con, f);
286 cursor += showShortOptions(con->options, f, NULL);
287 singleTableUsage(f, cursor, con->options, NULL);
289 if (con->otherHelp) {
290 cursor += strlen(con->otherHelp) + 1;
291 if (cursor > 79) fprintf(f, "\n ");
292 fprintf(f, " %s", con->otherHelp);
298 void poptSetOtherOptionHelp(poptContext con, const char * text) {
299 if (con->otherHelp) free(con->otherHelp);
300 con->otherHelp = g_strdup(text);