Main Page Namespace List Class Hierarchy Compound List File List Namespace Members Compound Members File Members Related Pages

# CmdLineParser.cpp

Go to the documentation of this file.

    00001
    00040 #include "CmdLineParser.h"
    00041 #include <iomanip.h>
    00042
    00043 /*
    00044           struct option {
    00045               const char *name;
    00046               int has_arg;
    00047               int *flag;
    00048               int val;
    00049           };
    00050
    00051        The meanings of the different fields are:
    00052
    00053        name   is the name of the long option.
    00054
    00055        has_arg
    00056               is:   no_argument   (or   0)  if  the  option  does  not  take  an  argument,
    00057               required_argument  (or  1)  if  the   option   requires   an   argument,   or
    00058               optional_argument (or 2) if the option takes an optional argument.
    00059
    00060        flag   specifies  how results are returned for a long option.  If flag is NULL, then
    00061               getopt_long() returns val.  (For example, the calling program may set val  to
    00062               the  equivalent short option character.)  Otherwise, getopt_long() returns 0,
    00063               and flag points to a variable which is set to val if the option is found, but
    00064               left unchanged if the option is not found.
    00065
    00066        val    is the value to return, or to load into the variable pointed to by flag.
    00067
    00068        The last element of the array has to be filled with zeroes.
    00069
    00070        If  longindex  is not NULL, it points to a variable which is set to the index of the
    00071        long option relative to longopts.
    00072
    00073 */
    00074
    00075 bool CmdLineParser::Parse(int argc, char** argv)
    00076 {
    00077         CmdLineArgT* pArg;
    00078         bool bError = false;
    00079         int c, i, j, nOptionIndex;
    00080
    00081         SetPrgName(argv[0]);
    00082
    00083         InitOptions();
    00084
    00085         OPTION* longOptions = new OPTION[m_nOptArgs + 1];
    00086         char* szShortOptions = new char[m_nOptArgs + 1];
    00087
    00088         for (i = 0, j = 0; i < m_nOptArgs; i++)
    00089         {
    00090                 pArg = m_pOptArgs[i];
    00091
    00092                 longOptions[i] = *pArg;
    00093
    00094                 if (pArg->HasShortName())
    00095                 {
    00096                         szShortOptions[j++] = pArg->GetShortName();
    00097
    00098                         if (pArg->HasOptArg())
    00099                                 szShortOptions[j++] = ':';
    00100                 }
    00101         }
    00102
    00103     longOptions[m_nOptArgs].SetToZero();
    00104         szShortOptions[j] = '\0';
    00105
    00106         while (true)
    00107         {
    00108                 c = getopt_long_only (argc, argv, szShortOptions, longOptions, &nOptionIndex);
    00109
    00110                 if (c == -1)
    00111                         break;
    00112                 else if (c == 0)
    00113                         pArg = m_pOptArgs[nOptionIndex];
    00114                 else if (c == '?') {
    00115                         bError = true;
    00116                         break;
    00117                 }
    00118                 else {
    00119                         // Find the arg that corresponds to the short option returned
    00120                         i = GetArgIndex(c);
    00121
    00122                         if (i >= 0)
    00123                                 pArg = m_pOptArgs[i];
    00124                         else {
    00125                                 printf ("?? getopt returned character code 0%o ??\n", c);
    00126                                 bError = true;
    00127                                 break;
    00128                         }
    00129                 }
    00130
    00131                 pArg->Select(optarg);
    00132         }
    00133
    00134         delete[] longOptions;
    00135         delete[] szShortOptions;
    00136
    00137         if (bError)
    00138         {
    00139                 ShowUsageMsg();
    00140                 return false;
    00141         }
    00142
    00143         // Process non-option ARGV-elements
    00144
    00145         if (optind < argc)
    00146         {
    00147                 m_pNonOptArgs = argv + optind;
    00148                 m_nNonOptArgs = argc - optind;
    00149         }
    00150
    00151         return true;
    00152 }
    00153
    00155 int CmdLineParser::GetArgIndex(char c)
    00156 {
    00157         for (int i = 0; i < m_nOptArgs; i++)
    00158                 if (c == m_pOptArgs[i]->GetShortName())
    00159                         return i;
    00160
    00161         return -1;
    00162 }
    00163
    00164 int CmdLineParser::GetArgIndex(const char* szArgName)
    00165 {
    00166         for (int i = 0; i < m_nOptArgs; i++)
    00167                 if (!strcmp(szArgName, m_pOptArgs[i]->GetLongName()))
    00168                         return i;
    00169
    00170         return -1;
    00171 }
    00172
    00173 bool CmdLineParser::IsSelected(char c)
    00174 {
    00175         int i = GetArgIndex(c);
    00176         return i >= 0 ? m_pOptArgs[i]->IsSelected():false;
    00177 }
    00178
    00179 bool CmdLineParser::IsSelected(const char* szArgName)
    00180 {
    00181         int i = GetArgIndex(szArgName);
    00182         return i >= 0 ? m_pOptArgs[i]->IsSelected():false;
    00183 }
    00184
    00185 void CmdLineParser::Print(ostream& os)
    00186 {
    00187         os << "\nParameter values:\n\n";
    00188
    00189         for (int i = 0; i < m_nOptArgs; i++)
    00190                 m_pOptArgs[i]->Print(os);
    00191
    00192         os << endl;
    00193 }
    00194
    00195 void CmdLineParser::ExecActions()
    00196 {
    00197         // Call the functions associated with the selected options
    00198         for (int i = 0; i < m_nOptArgs; i++)
    00199                 if (m_pOptArgs[i]->IsSelected() && m_pOptArgs[i]->HasAction())
    00200                         ExecAction(m_pOptArgs[i]->GetAction());
    00201 }
    00202
    00203 void CmdLineParser::SetPrgName(const char* szProgramName)
    00204 {
    00205         int len = strlen(szProgramName);
    00206         int i;
    00207         char c;
    00208
    00209         for (i = len - 1; i >= 0; i--)
    00210         {
    00211                 c = szProgramName[i];
    00212
    00213                 if (c == '/' || c == '\\')
    00214                 {
    00215                         i++;
    00216                         break;
    00217                 }
    00218         }
    00219
    00220         m_szProgramName = szProgramName + i;
    00221 }
    00222
    00223 void CmdLineParser::ShowUsageMsg()
    00224 {
    00225         const int FCS = 30; // first column size
    00226         char szLine[512];
    00227         char* p;
    00228
    00229         CmdLineArgT* pArg;
    00230
    00231         cerr << "\nUsage:\n\t" << m_szProgramName << " [options] ";
    00232
    00233         if (m_szOptArgHelp)
    00234                 cerr << m_szOptArgHelp;
    00235
    00236         cerr << "\n\nOptions:\n";
    00237
    00238         for (int i = 0; i < m_nOptArgs; i++)
    00239         {
    00240                 pArg = m_pOptArgs[i];
    00241                 p = szLine;
    00242
    00243                 strcpy(szLine, "\t");
    00244                 p += strlen(p);
    00245
    00246                 if (pArg->HasShortName())
    00247                 {
    00248                         sprintf(p, "-%c ", pArg->GetShortName());
    00249                         p += strlen(p);
    00250                 }
    00251
    00252                 if (pArg->HasLongName())
    00253                 {
    00254                         if (pArg->HasShortName())
    00255                         {
    00256                                 strcpy(p, "or ");
    00257                                 p += strlen(p);
    00258                         }
    00259
    00260                         sprintf(p, "-%s ", pArg->GetLongName());
    00261                         p += strlen(p);
    00262                 }
    00263
    00264                 if (pArg->HasOptArg())
    00265                 {
    00266                         sprintf(p, "[val]");
    00267                         p += strlen(p);
    00268                 }
    00269
    00270                 for (; p < szLine + FCS; p++)
    00271                         *p = ' ';
    00272
    00273                 strcpy(p, pArg->GetDesc());
    00274
    00275                 cerr << szLine << endl;
    00276         }
    00277
    00278         Print(cerr);
    00279
    00280         ShowUsageExamples();
    00281 }
    00282
    00283 void CmdLineParser::ShowErrorMsg(const char* szMsg)
    00284 {
    00285         cerr << endl << "Incorrect command line argument(s): "
    00286                 << szMsg << endl << endl;
    00287 }
    00288
    00290 LPCSTR asciitoascii(LPCSTR sz)
    00291 {
    00292         return sz;
    00293 }