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 */
20 static void displayArgs(poptContext con
, enum poptCallbackReason foo
,
21 struct poptOption
* key
,
22 const char * arg
, void * data
)
28 if (key
->shortName
== '?')
29 poptPrintHelp(con
, stdout
, 0);
31 poptPrintUsage(con
, stdout
, 0);
35 struct poptOption
const poptHelpOptions
[] = {
36 { NULL
, '\0', POPT_ARG_CALLBACK
, (void *)&displayArgs
, '\0', NULL
, NULL
},
37 { "help", '?', 0, NULL
, '?', N_("Show this help message"), NULL
},
38 { "usage", '\0', 0, NULL
, 'u', N_("Display brief usage message"), NULL
},
39 { NULL
, '\0', 0, NULL
, 0, NULL
, NULL
}
44 getTableTranslationDomain(const struct poptOption
*table
)
46 const struct poptOption
*opt
;
49 opt
->longName
|| opt
->shortName
|| opt
->arg
;
51 if(opt
->argInfo
== POPT_ARG_INTL_DOMAIN
)
58 static const char * getArgDescrip(const struct poptOption
* opt
,
59 const char *translation_domain
) {
60 (void) translation_domain
;
62 if (!(opt
->argInfo
& POPT_ARG_MASK
)) return NULL
;
64 if (opt
== (poptHelpOptions
+ 1) || opt
== (poptHelpOptions
+ 2))
65 if (opt
->argDescrip
) return POPT_(opt
->argDescrip
);
67 if (opt
->argDescrip
) return D_(translation_domain
, opt
->argDescrip
);
71 static void singleOptionHelp(FILE * f
, int maxLeftCol
,
72 const struct poptOption
* opt
,
73 const char *translation_domain
) {
74 int indentLength
= maxLeftCol
+ 5;
75 int lineLength
= 79 - indentLength
;
76 const char * help
= D_(translation_domain
, opt
->descrip
);
80 const char * argDescrip
= getArgDescrip(opt
, translation_domain
);
82 left
= malloc(maxLeftCol
+ 1);
85 if (opt
->longName
&& opt
->shortName
)
86 sprintf(left
, "-%c, --%s", opt
->shortName
, opt
->longName
);
87 else if (opt
->shortName
)
88 sprintf(left
, "-%c", opt
->shortName
);
89 else if (opt
->longName
)
90 sprintf(left
, "--%s", opt
->longName
);
94 strcat(left
, argDescrip
);
98 fprintf(f
," %-*s ", maxLeftCol
, left
);
100 fprintf(f
," %s\n", left
);
104 helpLength
= strlen(help
);
105 while (helpLength
> lineLength
) {
106 ch
= help
+ lineLength
- 1;
107 while (ch
> help
&& !isspace((unsigned char) *ch
)) ch
--;
108 if (ch
== help
) break; /* give up */
109 while (ch
> (help
+ 1) && isspace((unsigned char) *ch
)) ch
--;
112 fprintf(f
, "%.*s\n%*s", (int) (ch
- help
), help
, indentLength
, " ");
114 while (isspace((unsigned char) *help
) && *help
) help
++;
115 helpLength
= strlen(help
);
118 if (helpLength
) fprintf(f
, "%s\n", help
);
124 static int maxArgWidth(const struct poptOption
* opt
,
125 const char * translation_domain
) {
130 while (opt
->longName
|| opt
->shortName
|| opt
->arg
) {
131 if ((opt
->argInfo
& POPT_ARG_MASK
) == POPT_ARG_INCLUDE_TABLE
) {
132 this = maxArgWidth(opt
->arg
, translation_domain
);
133 if (this > max
) max
= this;
134 } else if (!(opt
->argInfo
& POPT_ARGFLAG_DOC_HIDDEN
)) {
135 this = opt
->shortName
? 2 : 0;
138 this += strlen(opt
->longName
) + 2;
141 s
= getArgDescrip(opt
, translation_domain
);
143 this += strlen(s
) + 1;
144 if (this > max
) max
= this;
153 static void singleTableHelp(FILE * f
, const struct poptOption
* table
,
155 const char *translation_domain
) {
156 const struct poptOption
* opt
;
157 const char *sub_transdom
;
160 while (opt
->longName
|| opt
->shortName
|| opt
->arg
) {
161 if ((opt
->longName
|| opt
->shortName
) &&
162 !(opt
->argInfo
& POPT_ARGFLAG_DOC_HIDDEN
))
163 singleOptionHelp(f
, left
, opt
, translation_domain
);
168 while (opt
->longName
|| opt
->shortName
|| opt
->arg
) {
169 if ((opt
->argInfo
& POPT_ARG_MASK
) == POPT_ARG_INCLUDE_TABLE
) {
170 sub_transdom
= getTableTranslationDomain(opt
->arg
);
172 sub_transdom
= translation_domain
;
175 fprintf(f
, "\n%s\n", D_(sub_transdom
, opt
->descrip
));
177 singleTableHelp(f
, opt
->arg
, left
, sub_transdom
);
183 static int showHelpIntro(poptContext con
, FILE * f
) {
187 fprintf(f
, _("Usage:"));
188 if (!(con
->flags
& POPT_CONTEXT_KEEP_FIRST
)) {
189 fn
= con
->optionStack
->argv
[0];
190 if (strrchr(fn
, '/')) fn
= strrchr(fn
, '/') + 1;
191 fprintf(f
, " %s", fn
);
192 len
+= strlen(fn
) + 1;
198 int poptPrintHelp(poptContext con
, FILE * f
, int flags
) {
203 showHelpIntro(con
, f
);
205 fprintf(f
, " %s\n", con
->otherHelp
);
207 fprintf(f
, " %s\n", POPT_("[OPTION...]"));
209 leftColWidth
= maxArgWidth(con
->options
, NULL
);
210 singleTableHelp(f
, con
->options
, leftColWidth
, NULL
);
214 static int singleOptionUsage(FILE * f
, int cursor
,
215 const struct poptOption
* opt
,
216 const char *translation_domain
) {
219 const char * item
= shortStr
;
220 const char * argDescrip
= getArgDescrip(opt
, translation_domain
);
222 if (opt
->shortName
) {
223 if (!(opt
->argInfo
& POPT_ARG_MASK
))
224 return cursor
; /* we did these already */
226 *shortStr
= opt
->shortName
;
228 } else if (opt
->longName
) {
229 len
+= 1 + strlen(opt
->longName
);
230 item
= opt
->longName
;
233 if (len
== 3) return cursor
;
236 len
+= strlen(argDescrip
) + 1;
238 if ((cursor
+ len
) > 79) {
243 fprintf(f
, " [-%s%s%s%s]", opt
->shortName
? "" : "-", item
,
244 argDescrip
? (opt
->shortName
? " " : "=") : "",
245 argDescrip
? argDescrip
: "");
247 return cursor
+ len
+ 1;
250 static int singleTableUsage(FILE * f
, int cursor
, const struct poptOption
* table
,
251 const char *translation_domain
) {
252 const struct poptOption
* opt
;
255 while (opt
->longName
|| opt
->shortName
|| opt
->arg
) {
256 if ((opt
->argInfo
& POPT_ARG_MASK
) == POPT_ARG_INTL_DOMAIN
)
257 translation_domain
= (const char *)opt
->arg
;
258 else if ((opt
->argInfo
& POPT_ARG_MASK
) == POPT_ARG_INCLUDE_TABLE
)
259 cursor
= singleTableUsage(f
, cursor
, opt
->arg
,
261 else if ((opt
->longName
|| opt
->shortName
) &&
262 !(opt
->argInfo
& POPT_ARGFLAG_DOC_HIDDEN
))
263 cursor
= singleOptionUsage(f
, cursor
, opt
, translation_domain
);
271 static int showShortOptions(const struct poptOption
* opt
, FILE * f
,
273 char s
[300]; /* this is larger then the ascii set, so
274 it should do just fine */
278 memset(str
, 0, sizeof(s
));
281 while (opt
->longName
|| opt
->shortName
|| opt
->arg
) {
282 if (opt
->shortName
&& !(opt
->argInfo
& POPT_ARG_MASK
))
283 str
[strlen(str
)] = opt
->shortName
;
284 else if ((opt
->argInfo
& POPT_ARG_MASK
) == POPT_ARG_INCLUDE_TABLE
)
285 showShortOptions(opt
->arg
, f
, str
);
293 fprintf(f
, " [-%s]", s
);
294 return strlen(s
) + 4;
297 void poptPrintUsage(poptContext con
, FILE * f
, int flags
) {
302 cursor
= showHelpIntro(con
, f
);
303 cursor
+= showShortOptions(con
->options
, f
, NULL
);
304 singleTableUsage(f
, cursor
, con
->options
, NULL
);
306 if (con
->otherHelp
) {
307 cursor
+= strlen(con
->otherHelp
) + 1;
308 if (cursor
> 79) fprintf(f
, "\n ");
309 fprintf(f
, " %s", con
->otherHelp
);
315 void poptSetOtherOptionHelp(poptContext con
, const char * text
) {
316 if (con
->otherHelp
) free(con
->otherHelp
);
317 con
->otherHelp
= strdup(text
);