Logo Search packages:      
Sourcecode: bcrypt version File versions  Download package

getopt.c

//GETOPT.C
/***************************************************************************** 
* 
*  MODULE NAME : GETOPT.C 
* 
*  COPYRIGHTS: 
*             This module contains code made available by IBM 
*             Corporation on an AS IS basis.  Any one receiving the 
*             module is considered to be licensed under IBM copyrights 
*             to use the IBM-provided source code in any way he or she 
*             deems fit, including copying it, compiling it, modifying 
*             it, and redistributing it, with or without 
*             modifications.  No license under any IBM patents or 
*             patent applications is to be implied from this copyright 
*             license. 
* 
*             A user of the module should understand that IBM cannot 
*             provide technical support for the module and will not be 
*             responsible for any consequences of use of the program. 
*  *             Any notices, including this one, are not to be removed 
*             from the module without the prior written consent of 
*             IBM. 
* 
*  AUTHOR:   Original author: 
*                 G. R. Blair (BOBBLAIR at AUSVM1) 
*                 Internet: bobblair@bobblair.austin.ibm.com 
* 
*            Extensively revised by: 
*                 John Q. Walker II, Ph.D. (JOHHQ at RALVM6) 
*                 Internet: johnq@ralvm6.vnet.ibm.com 
* 
*****************************************************************************/

/****************************************************************************** 
 * getopt() 
 * 
 * The getopt() function is a command line parser.  It returns the next 
 * option character in argv that matches an option character in opstring. 
 * 
 * The argv argument points to an array of argc+1 elements containing argc 
 * pointers to character strings followed by a null pointer. 
 * 
 * The opstring argument points to a string of option characters; if an 
 * option character is followed by a colon, the option is expected to have 
 * an argument that may or may not be separated from it by white space. 
 * The external variable optarg is set to point to the start of the option 
 * argument on return from getopt(). 
 * 
 * The getopt() function places in optind the argv index of the next argument 
 * to be processed.  The system initializes the external variable optind to 
 * 1 before the first call to getopt(). 
 * 
 * When all options have been processed (that is, up to the first nonoption 
 * argument), getopt() returns EOF.  The special option "--" may be used to 
 * delimit the end of the options; EOF will be returned, and "--" will be 
 * skipped. 
 * 
 * The getopt() function returns a question mark (?) when it encounters an 
 * option character not included in opstring.  This error message can be 
 * disabled by setting opterr to zero.  Otherwise, it returns the option 
 * character that was detected. 
 * 
 * If the special option "--" is detected, or all options have been 
 * processed, EOF is returned. 
 * 
 * Options are marked by either a minus sign (-) or a slash (/). 
 * 
 * No errors are defined. 
 *****************************************************************************/  
#include <stdio.h>                  /* for EOF */ 
#include <string.h>                 /* for strchr() */


/* static (global) variables that are specified as exported by getopt() */ 
char *optarg = NULL;    /* pointer to the start of the option argument  */ 
int   optind = 1;       /* number of the next argv[] to be evaluated    */ 
int   opterr = 1;       /* non-zero if a question mark should be returned 
                           when a non-valid option character is detected */  

/* handle possible future character set concerns by putting this in a macro */ 
#define _next_char(string)  (char)(*(string+1))

int getopt(int argc, char *argv[], char *opstring) 
{
    static char *pIndexPosition = NULL; /* place inside current argv string */
    char *pArgString = NULL;        /* where to start from next */
    char *pOptString;               /* the string in our program */


    if (pIndexPosition != NULL) {
      /* we last left off inside an argv string */
      if (*(++pIndexPosition)) {             
            /* there is more to come in the most recent argv */             
            pArgString = pIndexPosition;
      }
    }
    
    if (pArgString == NULL) {
      /* we didn't leave off in the middle of an argv string */
      if (optind >= argc) {
            /* more command-line arguments than the argument count */
            pIndexPosition = NULL;  /* not in the middle of anything */
            return EOF;             /* used up all command-line arguments */
      }
      
            /*---------------------------------------------------------------------         
             * If the next argv[] is not an option, there can be no more options.         
             *-------------------------------------------------------------------*/
            pArgString = argv[optind++]; /* set this to the next argument ptr */

            if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */
                  ('-' != *pArgString)) {
                  --optind;               /* point to current arg once we're done */
                  optarg = NULL;          /* no argument follows the option */
                  pIndexPosition = NULL;  /* not in the middle of anything */
                  return EOF;             /* used up all the command-line flags */
            }

            /* check for special end-of-flags markers */         
            if ((strcmp(pArgString, "-") == 0) ||
                  (strcmp(pArgString, "--") == 0)) {
                  optarg = NULL;          /* no argument follows the option */
                  pIndexPosition = NULL;  /* not in the middle of anything */
                  return EOF;             /* encountered the special flag */         
            }

            pArgString++;               /* look past the / or - */
      }
      
      if (':' == *pArgString) {       /* is it a colon? */
          /*---------------------------------------------------------------------         
           * Rare case: if opterr is non-zero, return a question mark;          
           * otherwise, just return the colon we're on.          
           *-------------------------------------------------------------------*/
          return (opterr ? (int)'?' : (int)':');     
      }
      else if ((pOptString = strchr(opstring, *pArgString)) == 0) {
          /*---------------------------------------------------------------------          
           * The letter on the command-line wasn't any good.          
           *-------------------------------------------------------------------*/         
          optarg = NULL;              /* no argument follows the option */         
          pIndexPosition = NULL;      /* not in the middle of anything */         
          return (opterr ? (int)'?' : (int)*pArgString);     
      }
      else {         
          /*---------------------------------------------------------------------          
           * The letter on the command-line matches one we expect to see          
           *-------------------------------------------------------------------*/         
          if (':' == _next_char(pOptString)) { /* is the next letter a colon? */             
              /* It is a colon.  Look for an argument string. */             
              if ('\0' != _next_char(pArgString)) {  /* argument in this argv? */                 
                  optarg = &pArgString[1];   /* Yes, it is */             
              }
              else {                 
                  /*-------------------------------------------------------------                  
                   * The argument string must be in the next argv.                  
                   * But, what if there is none (bad input from the user)?                  
                   * In that case, return the letter, and optarg as NULL.                  
                   *-----------------------------------------------------------*/                 
                  if (optind < argc)                     
                      optarg = argv[optind++];                
                  else {
                      optarg = NULL;
                      return (opterr ? (int)'?' : (int)*pArgString);
                  }
              }
              pIndexPosition = NULL;  /* not in the middle of anything */         
          }
          else {
              /* it's not a colon, so just return the letter */
              optarg = NULL;          /* no argument follows the option */
              pIndexPosition = pArgString;    /* point to the letter we're on */
          }
          return (int)*pArgString;    /* return the letter that matched */
      }
} 


Generated by  Doxygen 1.6.0   Back to index