Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

XGetopt.c

Go to the documentation of this file.
00001 // XGetopt.cpp  Version 1.1
00002 //
00003 // Author:  Hans Dietrich
00004 //          hdietrich2@hotmail.com
00005 //
00006 // Modified: David Smith
00007 //           dave.s@earthcorp.com
00008 //           Moved two char declarations from body of function so
00009 //           that it can compile as a C function.
00010 //           Thanks so much Hans
00011 //
00012 // This software is released into the public domain.
00013 // You are free to use it in any way you like.
00014 //
00015 // This software is provided "as is" with no expressed
00016 // or implied warranty.  I accept no liability for any
00017 // damage or loss of business that this software may cause.
00018 //
00020 
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include "XGetopt.h"
00024 
00026 //
00027 //  X G e t o p t . c p p
00028 //
00029 //
00030 //  NAME
00031 //       getopt -- parse command line options
00032 //
00033 //  SYNOPSIS
00034 //       int getopt(int argc, char *argv[], char *optstring)
00035 //
00036 //       extern char *optarg;
00037 //       extern int optind;
00038 //
00039 //  DESCRIPTION
00040 //       The getopt() function parses the command line arguments. Its
00041 //       arguments argc and argv are the argument count and array as
00042 //       passed into the application on program invocation.  In the case
00043 //       of Visual C++ programs, argc and argv are available via the
00044 //       variables __argc and __argv (double underscores), respectively.
00045 //       getopt returns the next option letter in argv that matches a
00046 //       letter in optstring.
00047 //
00048 //       optstring is a string of recognized option letters;  if a letter
00049 //       is followed by a colon, the option is expected to have an argument
00050 //       that may or may not be separated from it by white space.  optarg
00051 //       is set to point to the start of the option argument on return from
00052 //       getopt.
00053 //
00054 //       Option letters may be combined, e.g., "-ab" is equivalent to
00055 //       "-a -b".  Option letters are case sensitive.
00056 //
00057 //       getopt places in the external variable optind the argv index
00058 //       of the next argument to be processed.  optind is initialized
00059 //       to 0 before the first call to getopt.
00060 //
00061 //       When all options have been processed (i.e., up to the first
00062 //       non-option argument), getopt returns EOF, optarg will point
00063 //       to the argument, and optind will be set to the argv index of
00064 //       the argument.  If there are no non-option arguments, optarg
00065 //       will be set to NULL.
00066 //
00067 //       The special option "--" may be used to delimit the end of the
00068 //       options;  EOF will be returned, and "--" (and everything after it)
00069 //       will be skipped.
00070 //
00071 //  RETURN VALUE
00072 //       For option letters contained in the string optstring, getopt
00073 //       will return the option letter.  getopt returns a question mark (?)
00074 //       when it encounters an option letter not included in optstring.
00075 //       EOF is returned when processing is finished.
00076 //
00077 //  BUGS
00078 //       1)  Long options are not supported.
00079 //       2)  The GNU double-colon extension is not supported.
00080 //       3)  The environment variable POSIXLY_CORRECT is not supported.
00081 //       4)  The + syntax is not supported.
00082 //       5)  The automatic permutation of arguments is not supported.
00083 //       6)  This implementation of getopt() returns EOF if an error is
00084 //           encountered, instead of -1 as the latest standard requires.
00085 //
00086 //  EXAMPLE
00087 //       BOOL CMyApp::ProcessCommandLine(int argc, char *argv[])
00088 //       {
00089 //           int c;
00090 //
00091 //           while ((c = getopt(argc, argv, "aBn:")) != EOF)
00092 //           {
00093 //               switch (c)
00094 //               {
00095 //                   case 'a':
00096 //                       TRACE(_T("option a\n"));
00097 //                       //
00098 //                       // set some flag here
00099 //                       //
00100 //                       break;
00101 //
00102 //                   case 'B':
00103 //                       TRACE( _T("option B\n"));
00104 //                       //
00105 //                       // set some other flag here
00106 //                       //
00107 //                       break;
00108 //
00109 //                   case 'n':
00110 //                       TRACE(_T("option n: value=%d\n"), atoi(optarg));
00111 //                       //
00112 //                       // do something with value here
00113 //                       //
00114 //                       break;
00115 //
00116 //                   case '?':
00117 //                       TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
00118 //                       return FALSE;
00119 //                       break;
00120 //
00121 //                   default:
00122 //                       TRACE(_T("WARNING: no handler for option %c\n"), c);
00123 //                       return FALSE;
00124 //                       break;
00125 //               }
00126 //           }
00127 //           //
00128 //           // check for non-option args here
00129 //           //
00130 //           return TRUE;
00131 //       }
00132 //
00134 
00135 char    *optarg;        // global argument pointer
00136 int     optind = 0;     // global argv index
00137 
00138 int getopt(int argc, char *argv[], char *optstring)
00139 {
00140     static char *next = NULL;
00141   char c, *cp;
00142     if (optind == 0)
00143         next = NULL;
00144 
00145     optarg = NULL;
00146 
00147     if (next == NULL || *next == '\0')
00148     {
00149         if (optind == 0)
00150             optind++;
00151 
00152         if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
00153         {
00154             optarg = NULL;
00155             if (optind < argc)
00156                 optarg = argv[optind];
00157             return EOF;
00158         }
00159 
00160         if (strcmp(argv[optind], "--") == 0)
00161         {
00162             optind++;
00163             optarg = NULL;
00164             if (optind < argc)
00165                 optarg = argv[optind];
00166             return EOF;
00167         }
00168 
00169         next = argv[optind]+1;
00170         optind++;
00171     }
00172 
00173     c = *next++;
00174     cp = strchr(optstring, c);
00175 
00176     if (cp == NULL || c == ':')
00177         return '?';
00178 
00179     cp++;
00180     if (*cp == ':')
00181     {
00182         if (*next != '\0')
00183         {
00184             optarg = next;
00185             next = NULL;
00186         }
00187         else if (optind < argc)
00188         {
00189             optarg = argv[optind];
00190             optind++;
00191         }
00192         else
00193         {
00194             return '?';
00195         }
00196     }
00197 
00198     return c;
00199 }

Generated on Tue Aug 5 12:06:14 2008 for 'LibPst' by  doxygen 1.3.9.1