00001
00014 #include <cctype>
00015 #include <cmath>
00016 #include <iostream>
00017 #include <sstream>
00018 #include <string>
00019 #include <vector>
00020
00021 #include "popassert.h"
00022 #include "CVector3f.h"
00023 #include "CColor.h"
00024 #include "CCommand.h"
00025 #include "CCommandParser.h"
00026
00027
00028
00029
00030 CCommandParser* CCommandParser::s_pInstance = NULL;
00031
00032
00036 bool CCommandParser::StringToFloat(const std::string& StringNumber,
00037 float* pFloat)
00038 {
00039 bool ReturnValue = true;
00040 int DotCounter = 0;
00041
00042 for (int i = StringNumber.size() - 1; i >= 0 && ReturnValue; --i)
00043 {
00044 ReturnValue = false;
00045
00046 if (isdigit(StringNumber[i]))
00047 ReturnValue = true;
00048
00049 if (StringNumber[i] == '.' && DotCounter == 0)
00050 {
00051 ReturnValue = true;
00052 DotCounter++;
00053 }
00054
00055 if (StringNumber[i] == '-' && i == 0)
00056 ReturnValue = true;
00057 }
00058
00059 if (ReturnValue && pFloat)
00060 *pFloat = atof(StringNumber.c_str());
00061
00062 return ReturnValue;
00063 }
00064
00065
00066
00070 bool CCommandParser::StringToInt(const std::string& StringNumber,
00071 int* pInt)
00072 {
00073 bool ReturnValue = true;
00074
00075 for (int i = StringNumber.size() - 1; i >= 0 && ReturnValue; --i)
00076 {
00077 ReturnValue = false;
00078
00079 if (isdigit(StringNumber[i]))
00080 ReturnValue = true;
00081
00082 if (StringNumber[i] == '-' && i == 0)
00083 ReturnValue = true;
00084 }
00085
00086 if (ReturnValue && pInt)
00087 *pInt = atoi(StringNumber.c_str());
00088
00089 return ReturnValue;
00090 }
00091
00092
00093
00094
00095
00100 CCommand CCommandParser::Parse(std::string StrCommand) const
00101 {
00102 int i;
00103 CCommand ReturnedCommand;
00104
00105
00106 for (i = StrCommand.size() - 1;
00107 i >= 0 && (StrCommand[i] == ' ' || StrCommand[i] == '\t');
00108 --i);
00109 StrCommand.erase(i+1, StrCommand.size() - i);
00110
00111
00112
00113 std::vector< std::string > Tokens;
00114 std::istringstream CommandStream(StrCommand);
00115 std::string TempString;
00116
00117 if (!CommandStream.eof())
00118 {
00119 CommandStream >> TempString;
00120
00121 while(!CommandStream.eof())
00122 {
00123 Tokens.push_back(TempString);
00124 CommandStream >> TempString;
00125 }
00126 Tokens.push_back(TempString);
00127 }
00128
00129 if (Tokens.size() == 0)
00130 {
00131 ReturnedCommand.m_CommandID = CCommand::COMMAND_END;
00132 return ReturnedCommand;
00133 }
00134
00135
00136
00137 for (i = 0;
00138 i < CCommand::COMMAND_END && Tokens[0] != CCommand::s_CommandString[i];
00139 ++i);
00140
00141 ReturnedCommand.m_CommandID = (CCommand::TYPE_COMMAND) i;
00142
00143 switch(ReturnedCommand.m_CommandID)
00144 {
00146
00147
00148
00150 case CCommand::COMMAND_PRINT:
00151 {
00152 if (Tokens.size() == 1)
00153 {
00154 std::cout << "Parameter error: usage: " << Tokens[0]
00155 << " STRING" << std::endl;
00156 ReturnedCommand.m_CommandID = CCommand::COMMAND_END;
00157 }
00158 }
00159 case CCommand::COMMAND_HELP:
00160 {
00161 if (Tokens.size() > 1)
00162 {
00163 for (i = 0;
00164 i < CCommand::PARAMETER_END && Tokens[1] != CCommand::s_ParameterString[i];
00165 ++i);
00166
00167 ReturnedCommand.m_ParameterID = (CCommand::TYPE_PARAMETER) i;
00168
00169 if (ReturnedCommand.m_ParameterID == CCommand::PARAMETER_END &&
00170 Tokens[1] != "all")
00171 {
00172 std::cout << "\'" << Tokens[1] << "\' is not a valid parameter." << std::endl;
00173 ReturnedCommand.m_CommandID = CCommand::COMMAND_END;
00174 }
00175
00176 if (Tokens.size() > 2)
00177 {
00178 std::cout << "Warning: ignored parameter(s): ";
00179 for (i = 2; i < (signed) Tokens.size(); ++i)
00180 std::cout << Tokens[i] << " ";
00181 std::cout << std::endl;
00182 }
00183 }
00184
00185 return ReturnedCommand;
00186 break;
00187 }
00188
00189
00191
00192
00193
00195 case CCommand::COMMAND_RUN:
00196 {
00197 if (Tokens.size() == 1)
00198 {
00199 return ReturnedCommand;
00200 }
00201 else
00202 {
00203 std::cout << "Warning: ignored parameter(s): ";
00204 for (i = 1; i < (signed) Tokens.size(); ++i)
00205 std::cout << Tokens[i] << " ";
00206 std::cout << std::endl;
00207 }
00208
00209 break;
00210 }
00211
00212
00214
00215
00216
00218 case CCommand::COMMAND_SET:
00219 {
00220
00221 ReturnedCommand.m_pData.Int = NULL;
00222
00223 if (Tokens.size() > 1)
00224 {
00225 for (i = 0;
00226 i < CCommand::PARAMETER_END && Tokens[1] != CCommand::s_ParameterString[i];
00227 ++i);
00228
00229 ReturnedCommand.m_ParameterID = (CCommand::TYPE_PARAMETER) i;
00230 }
00231
00232 switch (ReturnedCommand.GetParameterType())
00233 {
00234
00235 case CCommand::PARAMETERTYPE_STRING:
00236 {
00237 if (Tokens.size() == 3)
00238 {
00239 ReturnedCommand.m_pData.String = new std::string(Tokens[2]);
00240 }
00241 else
00242 {
00243 std::cout << "Parameter error: usage: " << Tokens[0] << " " << Tokens[1]
00244 << " STRING" << std::endl;
00245 ReturnedCommand.m_CommandID = CCommand::COMMAND_END;
00246 }
00247 break;
00248 }
00249
00250
00251 case CCommand::PARAMETERTYPE_FLOAT:
00252 {
00253 bool Valid = true;
00254 if (Tokens.size() == 3)
00255 {
00256 ReturnedCommand.m_pData.Float = new float;
00257
00258 if (!StringToFloat(Tokens[2], ReturnedCommand.m_pData.Float))
00259 {
00260 delete ReturnedCommand.m_pData.Float;
00261 ReturnedCommand.m_pData.Float = NULL;
00262 Valid = false;
00263 }
00264 }
00265 else
00266 {
00267 Valid = false;
00268 }
00269
00270 if (!Valid)
00271 {
00272 std::cout << "Parameter error: usage: " << Tokens[0] << " " << Tokens[1]
00273 << " FLOAT" << std::endl;
00274 ReturnedCommand.m_CommandID = CCommand::COMMAND_END;
00275 }
00276
00277 break;
00278 }
00279
00280
00281 case CCommand::PARAMETERTYPE_VECTOR:
00282 {
00283 bool Valid = true;
00284 ReturnedCommand.m_pData.Vector = new CVector3f;
00285 if (Tokens.size() == 5)
00286 {
00287 for (int k = 0; k < 3 && Valid; ++k)
00288 {
00289 Valid = Valid && StringToFloat(Tokens[k+2],
00290 &(*ReturnedCommand.m_pData.Vector)[k]);
00291 }
00292 }
00293 else
00294 {
00295 Valid = false;
00296 }
00297
00298 if (!Valid)
00299 {
00300 delete ReturnedCommand.m_pData.Vector;
00301 ReturnedCommand.m_pData.Vector = NULL;
00302 std::cout << "Parameter error: usage: " << Tokens[0] << " " << Tokens[1]
00303 << " FLOAT FLOAT FLOAT" << std::endl;
00304 ReturnedCommand.m_CommandID = CCommand::COMMAND_END;
00305 }
00306
00307 break;
00308 }
00309
00310
00311 case CCommand::PARAMETERTYPE_COLOR:
00312 {
00313 bool Valid = true;
00314 ReturnedCommand.m_pData.Color = new CColor;
00315 if (Tokens.size() == 6)
00316 {
00317 for (int k = 0; k < 4 && Valid; ++k)
00318 {
00319 Valid = Valid && StringToFloat(Tokens[k+2],
00320 &(*ReturnedCommand.m_pData.Color)[k]);
00321 }
00322 }
00323 else
00324 {
00325 Valid = false;
00326 }
00327
00328 if (!Valid)
00329 {
00330 delete ReturnedCommand.m_pData.Color;
00331 ReturnedCommand.m_pData.Color = NULL;
00332 std::cout << "Parameter error: usage: " << Tokens[0] << " " << Tokens[1]
00333 << " FLOAT FLOAT FLOAT FLOAT" << std::endl;
00334 ReturnedCommand.m_CommandID = CCommand::COMMAND_END;
00335 }
00336
00337 break;
00338 }
00339
00340
00341 case CCommand::PARAMETERTYPE_INT:
00342 {
00343 bool Valid = true;
00344 if (Tokens.size() == 3)
00345 {
00346 ReturnedCommand.m_pData.Int = new int;
00347
00348 if (!StringToInt(Tokens[2], ReturnedCommand.m_pData.Int))
00349 {
00350 delete ReturnedCommand.m_pData.Int;
00351 ReturnedCommand.m_pData.Int = NULL;
00352 Valid = false;
00353 }
00354 }
00355 else
00356 {
00357 Valid = false;
00358 }
00359
00360 if (!Valid)
00361 {
00362 std::cout << "Parameter error: usage: " << Tokens[0] << " " << Tokens[1]
00363 << " INTEGER" << std::endl;
00364 ReturnedCommand.m_CommandID = CCommand::COMMAND_END;
00365 }
00366
00367 break;
00368 }
00369
00370
00371 default:
00372 {
00373 std::cout << "Parameter error" << std::endl;
00374 ReturnedCommand.m_CommandID = CCommand::COMMAND_END;
00375 break;
00376 }
00377 }
00378 }
00379
00381
00382
00383
00385 case CCommand::COMMAND_QUIT:
00386 {
00387
00388
00389 break;
00390 }
00391
00392
00394
00395
00396
00398 case CCommand::COMMAND_END:
00399 default:
00400 {
00401 std::cout << "\'" << Tokens[0] << "\' is not a valid command." << std::endl;
00402 break;
00403 }
00404
00405 }
00406
00407 return ReturnedCommand;
00408 }
00409
00410
00411