| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- /** BEGIN COPYRIGHT BLOCK
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- *
- * License: GPL (version 3 or any later version).
- * See LICENSE for details.
- * END COPYRIGHT BLOCK **/
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- #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_init(int argc)
- {
- _getopt_ext_inited = 1;
- /* optind_ext = 1;*/
- optind_last = argc;
- _optind_firstHandled = argc;
- _optind_firstRecognized = argc;
- /* optind = 1;*/
- 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);
-
- }
|