con->finalArgvAlloced = argc * 2;
con->finalArgv = calloc( con->finalArgvAlloced, sizeof(*con->finalArgv) );
con->execAbsolute = 1;
+ con->arg_strip = NULL;
if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER"))
con->flags |= POPT_CONTEXT_POSIXMEHARDER;
}
con->finalArgvCount = 0;
+
+ if (con->arg_strip) {
+ PBM_FREE(con->arg_strip);
+ con->arg_strip = NULL;
+ }
}
/* Only one of longName, shortName may be set at a time */
return t;
}
+static void poptStripArg(poptContext con, int which)
+{
+ if(con->arg_strip == NULL) {
+ con->arg_strip = PBM_ALLOC(con->optionStack[0].argc);
+ }
+ PBM_SET(which, con->arg_strip);
+}
+
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
int poptGetNextOpt(poptContext con)
{
poptCallbackType cb = NULL;
const void * cbData = NULL;
const char * longArg = NULL;
+ int canstrip = 0;
while (!con->os->nextCharArg && con->os->next == con->os->argc
&& con->os > con->optionStack) {
/* Process next long option */
if (!con->os->nextCharArg) {
char * localOptString, * optString;
+ int thisopt;
if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) {
con->os->next++;
continue;
}
+ thisopt=con->os->next;
origOptString = con->os->argv[con->os->next++];
if (con->restLeftover || *origOptString != '-') {
return POPT_ERROR_BADOPT;
}
- if (!opt)
+ if (!opt) {
con->os->nextCharArg = origOptString + 1;
+ } else {
+ if(con->os == con->optionStack &&
+ opt->argInfo & POPT_ARGFLAG_STRIP) {
+ canstrip = 1;
+ poptStripArg(con, thisopt);
+ }
+ }
}
/* Process next short option */
if (con->os->next == con->os->argc)
return POPT_ERROR_NOARG;
+ /* make sure this isn't part of a short arg or the
+ result of an alias expansion */
+ if(con->os == con->optionStack &&
+ opt->argInfo & POPT_ARGFLAG_STRIP &&
+ canstrip) {
+ poptStripArg(con, con->os->next);
+ }
+
con->os->nextArg = expandNextArg(con, con->os->argv[con->os->next++]);
}
if (con->aliases) free(con->aliases);
if (con->otherHelp) xfree(con->otherHelp);
if (con->execPath) xfree(con->execPath);
+ if (con->arg_strip) PBM_FREE(con->arg_strip);
+
free(con);
}
const char * poptGetInvocationName(poptContext con) {
return con->os->argv[0];
}
+
+int poptStrippedArgv(poptContext con, int argc, char **argv)
+{
+ int i,j=1, numargs=argc;
+
+ for(i=1; i<argc; i++) {
+ if(PBM_ISSET(i, con->arg_strip)) {
+ numargs--;
+ }
+ }
+
+ for(i=1; i<argc; i++) {
+ if(PBM_ISSET(i, con->arg_strip)) {
+ continue;
+ } else {
+ if(j<numargs) {
+ argv[j++]=argv[i];
+ } else {
+ argv[j++]='\0';
+ }
+ }
+ }
+
+ return(numargs);
+}
#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_ARGFLAG_STRIP 0x20000000 /* strip this arg from argv (only applies to long args) */
#define POPT_CBFLAG_PRE 0x80000000 /* call the callback before parse */
#define POPT_CBFLAG_POST 0x40000000 /* call the callback after parse */
#define POPT_CBFLAG_INC_DATA 0x20000000 /* use data from the include line,
void poptPrintUsage(poptContext con, FILE * f, int flags);
void poptSetOtherOptionHelp(poptContext con, const char * text);
/*@observer@*/ const char * poptGetInvocationName(poptContext con);
+/* shuffles argv pointers to remove stripped args, returns new argc */
+int poptStrippedArgv(poptContext con, int argc, char **argv);
#ifdef __cplusplus
}