summaryrefslogtreecommitdiff
path: root/popt
diff options
context:
space:
mode:
authorjbj <devnull@localhost>1999-11-18 17:10:15 +0000
committerjbj <devnull@localhost>1999-11-18 17:10:15 +0000
commit3a6118d4194d9672b24cd7b357e6191f4eb47fde (patch)
tree903af338fd62fee09287106e65efd54d8ea2923e /popt
parent284ac8bec49c6a708dd096c17115c34c3cd8bc80 (diff)
downloadrpm-3a6118d4194d9672b24cd7b357e6191f4eb47fde.tar.gz
rpm-3a6118d4194d9672b24cd7b357e6191f4eb47fde.tar.bz2
rpm-3a6118d4194d9672b24cd7b357e6191f4eb47fde.zip
From: Dick Porter <dick@acm.org> --
Here is a patch for popt to implement selective argument stripping from argv. With this patch I can use popt in ORBit (the CORBA spec requires ORBs to remove all ORB options from argv), which allows me to export a popt option table to the rest of Gnome. There is also a bug fix included where a string was realloc()d into a space too small to hold the trailing NULL. CVS patchset: 3428 CVS date: 1999/11/18 17:10:15
Diffstat (limited to 'popt')
-rw-r--r--popt/po/popt.pot2
-rw-r--r--popt/popt.c61
-rw-r--r--popt/popt.h3
-rw-r--r--popt/poptint.h1
4 files changed, 65 insertions, 2 deletions
diff --git a/popt/po/popt.pot b/popt/po/popt.pot
index 169152227..6a3a1b492 100644
--- a/popt/po/popt.pot
+++ b/popt/po/popt.pot
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 1999-11-18 11:50-0500\n"
+"POT-Creation-Date: 1999-11-18 11:59-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/popt/popt.c b/popt/popt.c
index 0de68fdce..ae608f197 100644
--- a/popt/popt.c
+++ b/popt/popt.c
@@ -67,6 +67,7 @@ poptContext poptGetContext(const char * name, int argc, const char ** argv,
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;
@@ -123,6 +124,11 @@ void poptResetContext(poptContext con) {
}
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 */
@@ -378,6 +384,14 @@ static /*@only@*/ const char * expandNextArg(poptContext con, const char * s)
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)
{
@@ -389,6 +403,7 @@ 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) {
@@ -403,11 +418,13 @@ int poptGetNextOpt(poptContext con)
/* 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 != '-') {
@@ -459,8 +476,15 @@ int poptGetNextOpt(poptContext con)
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 */
@@ -510,6 +534,14 @@ int poptGetNextOpt(poptContext con)
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++]);
}
@@ -624,6 +656,8 @@ void poptFreeContext(poptContext con) {
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);
}
@@ -713,3 +747,28 @@ int poptStuffArgs(poptContext con, const char ** argv) {
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);
+}
diff --git a/popt/popt.h b/popt/popt.h
index 5046fade2..e6fa8bdff 100644
--- a/popt/popt.h
+++ b/popt/popt.h
@@ -30,6 +30,7 @@ extern "C" {
#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,
@@ -119,6 +120,8 @@ void poptPrintHelp(poptContext con, FILE * f, int flags);
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
}
diff --git a/popt/poptint.h b/popt/poptint.h
index 168809541..a1edb97c4 100644
--- a/popt/poptint.h
+++ b/popt/poptint.h
@@ -59,6 +59,7 @@ struct poptContext_s {
/*@only@*/ const char * execPath;
int execAbsolute;
/*@only@*/ const char * otherHelp;
+ pbm_set * arg_strip;
};
#define xfree(_a) free((void *)_a)