00001
00040 #include "CmdLineParser.h"
00041 #include <iomanip.h>
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
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
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
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
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;
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 }