A
.BR "long option" ,
common in GNU utilities, consists of two - characters followed by a
-string made up of letters, numbers and hyphens. Either type of option
-may be followed by an argument. A space separates a short option from
-its arguments; either a space or an = separates a long option from an
-argument.
+string made up of letters, numbers and hyphens. Long options are
+optionally allowed to begin with a single -, primarily to allow command-line
+compatibility between popt applications and X toolkit applications.
+Either type of option may be followed by an argument. A space separates a
+short option from its arguments; either a space or an = separates a long
+option from an argument.
.sp
The popt library is highly portable and should work on any POSIX
platform. The latest version is always available from:
.BR POPT_ARG_LONG " A long integer is expected long"
.sp
.fi
+If \fIargInfo\fR value is logically or'd with \fBPOPT_ARGFLAG_ONEDASH\fR,
+the long argument may be given with a single - instead of two. For example,
+if \fB--longopt\fR is an option with \fBPOPT_ARGFLAG_ONEDASH\fR, is
+specified, \fB-longopt\fR is accepted as well.
+.sp
.RI "The next element, " arg ", allows popt to automatically update "
.RI "program variables when the option is used. If " arg " is "
.BR NULL ", it is ignored and popt takes no special action. "
All the leftover arguments are returned in a manner identical to
.IR argv ". The final element in the returned array points to "
.BR NULL ", indicating the end of the arguments.
+.sp
+.SS "5. AUTOMATIC HELP MESSAGES"
+The \fBpopt\fR library can automatically generate help messages which
+describe the options a program accepts.
.PP
.SH "ERROR HANDLING"
All of the popt functions that can return errors return integers.
con->execAbsolute = allowAbsolute;
}
+static void invokeCallbacks(poptContext con, const struct poptOption * table,
+ int post) {
+ const struct poptOption * opt = table;
+ poptCallbackType cb;
+
+ while (opt->longName || opt->shortName || opt->arg) {
+ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
+ invokeCallbacks(con, opt->arg, post);
+ } else if (((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) &&
+ ((!post && (opt->argInfo & POPT_CBFLAG_PRE)) ||
+ ( post && (opt->argInfo & POPT_CBFLAG_POST)))) {
+ cb = opt->arg;
+ cb(con, post ? POPT_CALLBACK_REASON_POST : POPT_CALLBACK_REASON_PRE,
+ NULL, NULL, opt->descrip);
+ }
+ opt++;
+ }
+}
+
poptContext poptGetContext(char * name, int argc, char ** argv,
const struct poptOption * options, int flags) {
poptContext con = malloc(sizeof(*con));
if (name)
con->appName = strcpy(malloc(strlen(name) + 1), name);
+ invokeCallbacks(con, con->options, 0);
+
return con;
}
&& con->os > con->optionStack)
con->os--;
if (!con->os->nextCharArg && con->os->next == con->os->argc) {
+ invokeCallbacks(con, con->options, 1);
if (con->doExec) execCommand(con);
return -1;
}
}
if (cb)
- cb(con, opt, con->os->nextArg, cbData);
+ cb(con, POPT_CALLBACK_REASON_OPTION, opt, con->os->nextArg, cbData);
else if (opt->val)
done = 1;
callback data to pass */
#define POPT_ARG_MASK 0x0000FFFF
#define POPT_ARGFLAG_ONEDASH 0x80000000 /* allow -longoption */
+#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /* don't show in help/usage */
+#define POPT_CBFLAG_PRE 0x80000000 /* call the callback before parse */
+#define POPT_CBFLAG_POST 0x40000000 /* call the callback after parse */
#define POPT_ERROR_NOARG -10
#define POPT_ERROR_BADOPT -11
typedef struct poptOption * poptOption;
#define POPT_CB_USE_INCLUDE_DATA ((void *) -1)
+enum poptCallbackReason { POPT_CALLBACK_REASON_PRE,
+ POPT_CALLBACK_REASON_POST,
+ POPT_CALLBACK_REASON_OPTION };
typedef void (*poptCallbackType)(poptContext con,
+ enum poptCallbackReason reason,
const struct poptOption * opt,
const char * arg, void * data);
#include "popt.h"
#include "poptint.h"
-static void displayArgs(poptContext con, struct poptOption * key,
+static void displayArgs(poptContext con, enum poptCallbackReason foo,
+ struct poptOption * key,
const char * arg, void * data) {
if (key->shortName== '?')
poptPrintHelp(con, stderr, 0);
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
this = maxArgWidth(opt->arg);
- } else {
+ if (this > max) max = this;
+ } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
this = opt->shortName ? 2 : 0;
if (opt->longName) {
if (this) this += 2;
s = getArgDescrip(opt);
if (s)
this += strlen(s) + 1;
+ if (this > max) max = this;
}
- if (this > max) max = this;
-
opt++;
}
opt = table;
while (opt->longName || opt->shortName || opt->arg) {
- if (opt->longName || opt->shortName)
+ if ((opt->longName || opt->shortName) &&
+ !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
singleOptionHelp(f, left, opt);
opt++;
}
opt = table;
while (opt->longName || opt->shortName || opt->arg) {
- if (opt->longName || opt->shortName)
+ if ((opt->longName || opt->shortName) &&
+ !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
cursor = singleOptionUsage(f, cursor, opt);
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
cursor = singleTableUsage(f, cursor, opt->arg);
#include "popt.h"
-void option_callback(poptContext con, const struct poptOption * opt,
+void option_callback(poptContext con, enum poptCallbackReason reason,
+ const struct poptOption * opt,
char * arg, void * data) {
fprintf(stdout, "callback: %c %s %s ", opt->val, (char *) data, arg);
}
{ "arg3", '3', POPT_ARG_INT, &arg3, 0, "A third argument", "ANARG" },
{ "shortoption", '\0', POPT_ARGFLAG_ONEDASH, &shortopt, 0,
"Needs a single -", NULL },
+ { "hidden", '\0', POPT_ARG_STRING | POPT_ARGFLAG_DOC_HIDDEN, NULL, 0,
+ "This shouldn't show up", NULL },
{ "unused", '\0', POPT_ARG_STRING, NULL, 0,
"Unused option for help testing", "UNUSED" },
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, &moreArgs, 0, NULL },