00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <common/ARGParser.h>
00027 #include <common/Defines.h>
00028 #include <stdio.h>
00029
00030
00031
00032
00033
00034 ARGParser::Entry::Entry(ARGParserBoolI *destBoolArg,
00035 ARGParserIntI *destIntArg,
00036 ARGParserStringI *destStringArg,
00037 char **destCArg,
00038 int *destIArg,
00039 bool *destBArg,
00040 char *helpArg) :
00041 destBool(destBoolArg),
00042 destInt(destIntArg),
00043 destString(destStringArg),
00044 destC(destCArg),
00045 destI(destIArg),
00046 destB(destBArg),
00047 help(helpArg)
00048 {
00049
00050 }
00051
00052 ARGParser::ARGParser()
00053 {
00054
00055 }
00056
00057 ARGParser::~ARGParser()
00058 {
00059
00060 }
00061
00062 bool ARGParser::parse(int argc,char *argv[])
00063 {
00064 int i;
00065 std::string cmd, space=(" "), quote=("\"");
00066
00067 for (i=1; i<argc;i++)
00068 cmd += space + quote + argv[i] + quote;
00069
00070 return parse((char *)cmd.c_str());
00071 }
00072
00073 bool ARGParser::parse(char *lpCmdLine)
00074 {
00075 std::list<std::string> cmdLine;
00076
00077 if (!parseLineIntoStrings(lpCmdLine, cmdLine))
00078 {
00079 showArgs("ERROR: Unmatched parenthasis.\n\n");
00080 return false;
00081 }
00082
00083 while (!cmdLine.empty())
00084 {
00085 std::string &firstCommand = cmdLine.front();
00086 if (strcmp(firstCommand.c_str(), "-h") == 0 ||
00087 strcmp(firstCommand.c_str(), "-help") == 0)
00088 {
00089 showArgs();
00090 return false;
00091 }
00092
00093 std::map<std::string, Entry>::iterator itor = argMap_.find(firstCommand);
00094 if (itor != argMap_.end())
00095 {
00096 cmdLine.pop_front();
00097 if (!parseArg(itor->second, cmdLine))
00098 {
00099 return false;
00100 }
00101 }
00102 else if (!nonParamMap_.empty() &&
00103 firstCommand.c_str()[0] != '-')
00104 {
00105 if (!nonParamMap_.begin()->second.destString->
00106 setStringArgument(cmdLine.front().c_str()))
00107 {
00108 showArgs("ERROR: Parameter is not within allowed values\n\n");
00109 return false;
00110 }
00111 cmdLine.pop_front();
00112 }
00113 else
00114 {
00115 char buffer[255];
00116 snprintf(buffer, 255, "ERROR: Unknown parameter : \"%s\"\n\n", firstCommand.c_str());
00117 showArgs(buffer);
00118 return false;
00119 }
00120 }
00121
00122 return true;
00123 }
00124
00125 bool ARGParser::parseLineIntoStrings(char *line, std::list<std::string> &cmdLine)
00126 {
00127 bool inQuote = false;
00128 std::string currentEntry;
00129 for (int i=0; i<(int) strlen(line)+1; i++)
00130 {
00131 const char c = line[i];
00132
00133 if (c == '\0')
00134 {
00135 if (!currentEntry.empty()) cmdLine.push_back(currentEntry.c_str());
00136 currentEntry = "";
00137 }
00138 else if ((c == ' ') && !inQuote)
00139 {
00140 if (!currentEntry.empty()) cmdLine.push_back(currentEntry.c_str());
00141 currentEntry = "";
00142 }
00143 else if (c == '\"')
00144 {
00145 inQuote = !inQuote;
00146 }
00147 else
00148 {
00149 currentEntry += c;
00150 }
00151 }
00152
00153 return !inQuote;
00154 }
00155
00156 bool ARGParser::parseArg(ARGParser::Entry &newEntry, std::list<std::string> &cmdLine)
00157 {
00158 if (newEntry.destB)
00159 {
00160 *newEntry.destB = true;
00161 }
00162 else if (newEntry.destI)
00163 {
00164 if (!cmdLine.empty())
00165 {
00166 *newEntry.destI = atoi(cmdLine.front().c_str());
00167 cmdLine.pop_front();
00168 }
00169 else
00170 {
00171 showArgs("ERROR: Expected <int> parameter\n\n");
00172 return false;
00173 }
00174 }
00175 else if (newEntry.destC)
00176 {
00177 if (!cmdLine.empty())
00178 {
00179 *newEntry.destC = new char[strlen(cmdLine.front().c_str())+1];
00180 strcpy(*newEntry.destC, cmdLine.front().c_str());
00181 cmdLine.pop_front();
00182 }
00183 else
00184 {
00185 showArgs("ERROR: Expected <string> parameter\n\n");
00186 return false;
00187 }
00188 }
00189 else if (newEntry.destBool)
00190 {
00191 if (!newEntry.destBool->setBoolArgument(true))
00192 {
00193 showArgs("ERROR: Parameter is not within allowed values\n\n");
00194 return false;
00195 }
00196 }
00197 else if (newEntry.destInt)
00198 {
00199 if (!cmdLine.empty())
00200 {
00201 if (!newEntry.destInt->setIntArgument(atoi(cmdLine.front().c_str())))
00202 {
00203 showArgs("ERROR: Parameter is not within allowed values\n\n");
00204 return false;
00205 }
00206 cmdLine.pop_front();
00207 }
00208 else
00209 {
00210 showArgs("ERROR: Expected <int> parameter\n\n");
00211 return false;
00212 }
00213 }
00214 else if (newEntry.destString)
00215 {
00216 if (!cmdLine.empty())
00217 {
00218 if (!newEntry.destString->setStringArgument(cmdLine.front().c_str()))
00219 {
00220 showArgs("ERROR: Parameter is not within allowed values\n\n");
00221 return false;
00222 }
00223 cmdLine.pop_front();
00224 }
00225 else
00226 {
00227 showArgs("ERROR: Expected <string> parameter\n\n");
00228 return false;
00229 }
00230 }
00231 else
00232 {
00233 return false;
00234 }
00235
00236 return true;
00237 }
00238
00239 void ARGParser::showArgs(char *topString)
00240 {
00241 char buffer[4048];
00242 if (topString)
00243 {
00244 strcpy(buffer, topString);
00245 }
00246 else
00247 {
00248 buffer[0] = '\0';
00249 }
00250 strcat(buffer, "Usage : \n");
00251
00252 std::map<std::string, Entry>::iterator itor;
00253 for (itor = argMap_.begin();
00254 itor != argMap_.end();
00255 itor++)
00256 {
00257 char *type = "unknown";
00258 if (itor->second.destC || itor->second.destString) type = "<string>";
00259 else if (itor->second.destB || itor->second.destBool) type = "";
00260 else if (itor->second.destI || itor->second.destInt) type = "<int>";
00261
00262 char buffer2[255];
00263 snprintf(buffer2, 255, "\t%s %s", itor->first.c_str(), type);
00264 if (itor->second.help.size())
00265 {
00266 strcat(buffer2, std::string(abs(10 - int(strlen(buffer2))), ' ').c_str());
00267 strcat(buffer2, itor->second.help.c_str());
00268 }
00269 strcat(buffer2, "\n");
00270
00271 strcat(buffer, buffer2);
00272 }
00273 for (itor = nonParamMap_.begin();
00274 itor != nonParamMap_.end();
00275 itor++)
00276 {
00277 char buffer2[255];
00278 strcat(buffer2, "\t[");
00279 strcat(buffer2, itor->first.c_str());
00280 strcat(buffer2, "]");
00281 if (itor->second.help.size())
00282 {
00283 strcat(buffer2, std::string(abs(10 - int(strlen(buffer2))), ' ').c_str());
00284 strcat(buffer2, itor->second.help.c_str());
00285 }
00286 strcat(buffer2, "\n");
00287
00288 strcat(buffer, buffer2);
00289 }
00290
00291 S3D::dialogMessage("Arguments", buffer);
00292 }
00293
00294 void ARGParser::addEntry(char *cmd, char **destStr, char *help)
00295 {
00296 Entry newEntry(NULL, NULL, NULL, destStr, NULL, NULL, help);
00297 addNewEntry(cmd, newEntry);
00298 }
00299
00300 void ARGParser::addEntry(char *cmd, int *destI, char *help)
00301 {
00302 Entry newEntry(NULL, NULL, NULL, NULL, destI, NULL, help);
00303 addNewEntry(cmd, newEntry);
00304 }
00305
00306 void ARGParser::addEntry(char *cmd, bool *destB, char *help)
00307 {
00308 Entry newEntry(NULL, NULL, NULL, NULL, NULL, destB, help);
00309 addNewEntry(cmd, newEntry);
00310 }
00311
00312 void ARGParser::addEntry(char *cmd, ARGParserBoolI *destBool, char *help)
00313 {
00314 Entry newEntry(destBool, NULL, NULL, NULL, NULL, NULL, help);
00315 addNewEntry(cmd, newEntry);
00316 }
00317
00318 void ARGParser::addEntry(char *cmd, ARGParserIntI *destInt, char *help)
00319 {
00320 Entry newEntry(NULL, destInt, NULL, NULL, NULL, NULL, help);
00321 addNewEntry(cmd, newEntry);
00322 }
00323
00324 void ARGParser::addEntry(char *cmd, ARGParserStringI *destString, char *help)
00325 {
00326 Entry newEntry(NULL, NULL, destString, NULL, NULL, NULL, help);
00327 addNewEntry(cmd, newEntry);
00328 }
00329
00330 void ARGParser::addNewEntry(char *cmd, ARGParser::Entry &newEntry)
00331 {
00332 argMap_[cmd] = newEntry;
00333 }
00334
00335 void ARGParser::addNonParamEntry(char *cmd, ARGParserStringI *destString, char *help)
00336 {
00337 Entry newEntry(NULL, NULL, destString, NULL, NULL, NULL, help);
00338 nonParamMap_[cmd] = newEntry;
00339 }