summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/getopt_ext.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/servers/slapd/getopt_ext.c')
-rw-r--r--ldap/servers/slapd/getopt_ext.c236
1 files changed, 236 insertions, 0 deletions
diff --git a/ldap/servers/slapd/getopt_ext.c b/ldap/servers/slapd/getopt_ext.c
new file mode 100644
index 00000000..97d2e6d3
--- /dev/null
+++ b/ldap/servers/slapd/getopt_ext.c
@@ -0,0 +1,236 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#include "getopt_ext.h"
+
+char *optarg_ext;
+int optind_ext=1;
+int optopt_ext;
+int opterr_ext;
+int optind_last;
+
+static int _getopt_ext_inited = 0;
+static int _optind_firstHandled = 0;
+static int _optind_firstRecognized = 0;
+static int _getopt_ext_done_long = 0;
+
+static
+int _getopt_ext_init(int argc)
+{
+ _getopt_ext_inited = 1;
+ /* optind_ext = 1;*/
+ optind_last = argc;
+ _optind_firstHandled = argc;
+ _optind_firstRecognized = argc;
+ /* optind = 1;*/
+ _getopt_ext_done_long = 0;
+ return(0);
+}
+
+#if 0
+static
+int _getopt_ext_done()
+{
+ _getopt_ext_done_long = 1;
+ return(0);
+}
+#endif
+
+static
+int _getopt_ext_find(int argc,
+ char **argv,
+ const struct opt_ext *longOpts)
+{
+ int i=0;
+ struct opt_ext *lopt;
+
+ i=0;
+ lopt = (struct opt_ext *)longOpts;
+ while(lopt->o_string) {
+ if(0 != strcmp(argv[optind_ext]+2,lopt->o_string)) {
+ i++;
+ lopt++;
+ continue;
+ }
+ /*
+ * found it
+ */
+ return(i);
+ }
+ /* should never come here */
+ return(-1);
+}
+
+static
+int _getopt_ext_tailit(int argc,
+ char **argv,
+ int hasArg,
+ int recognized)
+{
+ char *_optPtr=NULL;
+ char *_optArgPtr=NULL;
+ int _endIndex=optind_last;
+ int _nextDest=optind_ext;
+ int _nextSource=optind_ext;
+
+ _optPtr = argv[optind_ext];
+ if(hasArg) {
+ _nextSource = optind_ext + 2;
+ _endIndex = ((recognized)?_optind_firstRecognized:_optind_firstHandled);
+ _optArgPtr = argv[optind_ext + 1];
+ } else {
+ _nextSource = optind_ext + 1;
+ _endIndex = ((recognized)?_optind_firstRecognized:_optind_firstHandled);
+ _optArgPtr = NULL;
+ }
+
+ while(_nextSource < _endIndex) {
+ argv[_nextDest] = argv[_nextSource];
+ _nextSource++;
+ _nextDest++;
+ }
+
+ argv[_nextDest] = _optPtr;
+ /* argv[_nextDest] = NULL; */
+ if(hasArg) {
+ argv[_nextDest + 1] = _optArgPtr;
+ if(recognized) {
+ _optind_firstRecognized -=2;
+ }
+ _optind_firstHandled -=2;
+ } else {
+ if(recognized) {
+ _optind_firstRecognized -=1;
+ }
+ _optind_firstHandled -=1;
+ }
+ optind_last = _optind_firstRecognized;
+ return(0);
+}
+
+/*
+ * First process all the long options (using exact string matches)
+ * Then, follow up with regular option processing using good ol' getopt
+ *
+ * return the same return codes as getopt
+ *
+ */
+
+int getopt_ext(int argc,
+ char **argv,
+ const char *optstring,
+ const struct opt_ext *longOpts,
+ int *longOptIndex)
+{
+ int retVal;
+
+ if(!_getopt_ext_inited) {
+ _getopt_ext_init(argc);
+ }
+
+ if(_optind_firstHandled < optind_ext) {
+ /* we are not processing extended options anymore...
+ let getopt handle it.
+ */
+ goto _doneWithExtendedOptions;
+ }
+
+ /*
+ * if we are here, we are not done with extended options...
+ *
+ */
+ while(_optind_firstHandled > optind_ext) {
+ if(0 != strncmp(argv[optind_ext], "--", 2)) {
+ optind_ext++;
+ continue;
+ }
+ /*
+ * possibly an extended option
+ */
+ retVal = _getopt_ext_find(argc,argv,longOpts);
+ if(-1 == retVal) {
+ /*
+ * unrecognized long option...
+ * we will let getopt handle it later...
+ *
+ */
+ optind_ext++;
+ continue;
+ }
+ /*
+ * we found an extended option
+ * now find its arg...
+ */
+ switch((longOpts+retVal)->o_type) {
+ case ArgNone:
+ default:
+ {
+ /* send this option to the end of the arglist */
+ _getopt_ext_tailit(argc,argv,0,1);
+ optarg_ext = NULL;
+ *longOptIndex = retVal;
+ return((longOpts+retVal)->o_return);
+ }
+ case ArgRequired:
+ {
+ /*
+ * make sure the next arg is a "valid" argument
+ */
+ if(((optind_ext + 1) == _optind_firstHandled)) {
+ /*
+ * did not find the argument
+ * let getopt handle it
+ * we will just push it to the end and continue
+ * looking for more extended options
+ *
+ * _getopt_ext_tailit(argc,argv,0,0);
+ */
+ optind_ext++;
+ fprintf(stderr, "%s: option requires an argument -- %s\n",
+ argv[0],(longOpts+retVal)->o_string);
+ exit(0);
+ continue;
+ }
+ /* like getopt, we don't care what the arg looks like! */
+ /* send this option to the end of the arglist */
+ _getopt_ext_tailit(argc,argv,1,1);
+ optarg_ext = argv[_optind_firstRecognized + 1];
+ *longOptIndex = retVal;
+ return((longOpts+retVal)->o_return);
+ }
+ case ArgOptional:
+ {
+ if(((optind_ext + 1) == optind_last) ||
+ ('-' == argv[optind_ext + 1][0])){
+ /*
+ * did not find the argument
+ *
+ */
+ _getopt_ext_tailit(argc,argv,0,1);
+ optarg_ext = NULL;
+ *longOptIndex = retVal;
+ return((longOpts+retVal)->o_return);
+ }
+ /* send this option to the end of the arglist */
+ _getopt_ext_tailit(argc,argv,1,1);
+ optarg_ext = argv[optind_last + 1];
+ *longOptIndex = retVal;
+ return((longOpts+retVal)->o_return);
+ }
+ }
+
+ /* optind_ext++;*/
+ }
+
+_doneWithExtendedOptions:
+ retVal = getopt(optind_last,argv,optstring);
+ optarg_ext = optarg;
+ /* optopt_ext = optopt; */
+ optind_last = _optind_firstHandled;
+ return(retVal);
+
+}
+