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 }

Generated on Sat Nov 13 11:21:21 2004 for Noisy DAG Matcher by doxygen1.2.18