CCommandParser.cpp

Go to the documentation of this file.
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 // Static members
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   // Remove the whitespace at the end of the string
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   // Tokenization of the string ; all tokens are stocked in a vector.
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   // Getting the ID of the command
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       //  "help" and "print" command  //
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       //  "run" command  //
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       //  "set" command  //
00216       //                 //
00218     case CCommand::COMMAND_SET:
00219       {
00220         // Taking care of the remaining parameters for the "set" function
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             // String
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             // Float
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             // Vector
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             // Color
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             // Int
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             // Default
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       //  "quit" command  //
00383       //                  //
00385     case CCommand::COMMAND_QUIT:
00386       {
00387         // Do nothing, just quit no matter what the
00388         // parameters are.
00389         break;
00390       }
00391 
00392 
00394       //                 //
00395       //  "end" command  //
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 

Generated on Fri Dec 5 03:20:33 2008 for Mathematical Ray-tracer by  doxygen 1.5.4