Page principale | Hiérarchie des classes | Liste alphabétique | Liste des classes | Liste des fichiers | Membres de classe | Membres de fichier

Script.cpp

Aller à la documentation de ce fichier.
00001 /*! \file Script.cpp
00002     \brief Interpréteur de script.
00003 
00004     Interprete des scripts structurés en fonctions.
00005 
00006     \author     aerith (www.aerith.fr)
00007     \version    1.0
00008     \date       20/11/2007
00009 */
00010 
00011 #include    "Script.h"
00012 
00013 MUTEX           Script::ScriptMutex;
00014 unsigned int    Script::ScriptInstance = 0;
00015 
00016 Script::Script()
00017 {
00018     if(!ScriptInstance)
00019         MutexInit(&ScriptMutex);
00020 
00021     ScriptInstance++;
00022 
00023     NoLine = 0;
00024     NoCar = 0;
00025 }
00026 
00027 Script::~Script()
00028 {
00029     while(Functions.size())
00030         DelFunction(Functions.size() - 1);
00031     Functions.clear();
00032 
00033     ScriptInstance--;
00034 
00035     if(!ScriptInstance)
00036         MutexStop(&ScriptMutex);
00037 }
00038 
00039 void    Script::LogError(char *pDesc)
00040 {
00041     FILE    *File;
00042 
00043     File = fopen("ScriptError.log", "a");
00044     if(File)
00045     {
00046         fprintf(File, "Line %i, Car %i => %s\n", NoLine, NoCar, pDesc);
00047 
00048         fclose(File);
00049     }
00050     else
00051         perror("Canot open Script's errors log file\n");
00052 }
00053 
00054 int     Script::AddFunction(char *pName, unsigned int iNb, SCRIPT_ROUTINE pFunction)
00055 {
00056     unsigned int    i = Functions.size();
00057 
00058     Functions.push_back(new ScriptFunc);
00059 
00060     if((i + 1) != Functions.size())
00061         return ERROR_C_MEMORY;
00062     else
00063     {
00064         Functions.back()->Name = new char[strlen(pName) + 1];
00065         strcpy(Functions.back()->Name, pName);
00066         Functions.back()->NbParam = iNb;
00067         Functions.back()->Function = pFunction;
00068     }
00069 
00070     return ERROR_C_NOERROR;
00071 }
00072 
00073 int     Script::DelFunction(unsigned int iPos)
00074 {
00075 
00076     if(iPos < Functions.size())
00077     {
00078         delete [] Functions[iPos]->Name;
00079         delete Functions[iPos];
00080         Functions.erase(Functions.begin() + iPos);
00081     }
00082     
00083     return ERROR_C_NOERROR;
00084 }
00085 
00086 int     Script::DelFunction(char *pName)
00087 {
00088     unsigned int    i;
00089 
00090     for(i = 0; i < Functions.size(); i++)
00091         if(!strcmp(Functions[i]->Name, pName))
00092             return DelFunction(i);
00093 
00094     return ERROR_C_NOERROR;
00095 }
00096 
00097 char    *Script::GetName(unsigned int iPos)
00098 {
00099     if(iPos < Functions.size())
00100         return Functions[iPos]->Name;
00101 
00102     return NULL;
00103 }
00104 
00105 int     Script::GetNbParam(unsigned int iPos)
00106 {
00107     if(iPos < Functions.size())
00108         return Functions[iPos]->NbParam;
00109 
00110     return 0;
00111 }
00112 
00113 int     Script::GetNbParam(char *pName)
00114 {
00115     unsigned int    i;
00116 
00117     for(i = 0; i < Functions.size(); i++)
00118         if(!strcmp(Functions[i]->Name, pName))
00119             return Functions[i]->NbParam;
00120 
00121     return 0;
00122 }
00123 
00124 int     Script::GetNbFunction()
00125 {
00126     return Functions.size();
00127 }
00128 
00129 String  Script::ParseFile(char *pName)
00130 {
00131     FILE    *File;
00132     char    Buffer[SCRIPT_BUFFER + 1];
00133     String  In;
00134     String  Out;
00135     BEGIN
00136 
00137     MutexLock(&ScriptMutex);
00138 
00139     File = fopen(pName, "r");
00140     if(File)
00141     {
00142         NoLine = 0;
00143         NoCar = 0;
00144 
00145         while(!feof(File) && !CERROR)
00146         {
00147             if(fgets(Buffer, SCRIPT_BUFFER, File))
00148             {
00149                 In = Buffer;
00150                 Out = Parse(In);
00151             }
00152         }
00153 
00154         fclose(File);
00155     }
00156     ENDTRY(ERROR_C_DATA_FILE)
00157 
00158     MutexUnLock(&ScriptMutex);
00159     
00160     PERROR
00161     
00162     return Out;
00163 }
00164 
00165 String  Script::Parse(String In)
00166 {
00167     char            *pIn;
00168     String          Name;
00169     ScriptParam     Params;
00170     String          Out;
00171     String          Temp;
00172     unsigned int    NoFunc = 0;
00173     bool            fComent = 0;
00174     bool            fParam = 0;
00175     bool            fFunc = 0;
00176     bool            fQuit = 0;
00177     BEGIN
00178 
00179     pIn = In.Data;
00180     Name = "";
00181     Out = "";
00182     Params.Vars = &Vars;
00183 
00184     do
00185     {
00186         switch(*pIn)
00187         {
00188             case '#'    : //commentaire
00189                 if(!fParam)
00190                     fComent = 1;
00191                 else
00192                     Name += *pIn;
00193                 break;
00194 
00195             case '\n'   : //changement de ligne
00196                 fComent = 0;
00197                 NoLine++;
00198                 NoCar = 0;
00199                 break;
00200 
00201             case '\0'   : //fin de fichier
00202                 if(fFunc || fParam)
00203                 {
00204                     LogError("End of file found\n");
00205                     CERROR = ERROR_C_SYNTAX;
00206                 }
00207                 break;
00208 
00209             case '\"'   : //chaine de carractère de paramètre
00210                 if(!fComent)
00211                 {
00212                     if(!fFunc)
00213                     {
00214                         LogError("Parameter found outside a function\n");
00215                         CERROR = ERROR_C_SYNTAX;
00216                         break;
00217                     }
00218 
00219                     if(fParam)
00220                     {
00221                         Params.Params.push_back(Name);
00222                         Name = "";
00223                     }
00224 
00225                     fParam = !fParam;
00226                 }
00227                 break;
00228 
00229             case '('    : //début des paramètres
00230                 if(!fParam && !fComent)
00231                 {
00232                     if(fFunc)
00233                     {
00234                         LogError("Function's name missing\n");
00235                         CERROR = ERROR_C_SYNTAX;
00236                         break;
00237                     }
00238 
00239                     for(NoFunc = 0; NoFunc < Functions.size(); NoFunc++)
00240                     {
00241                         if(strcpy(Functions[NoFunc]->Name, Name.Data))
00242                             break;
00243                     }
00244 
00245                     if(NoFunc == Functions.size())
00246                     {
00247                         LogError("Function not found\n");
00248                         CERROR = ERROR_C_FUNCTION;
00249                         break;
00250                     }
00251                     else
00252                     {
00253                         Name = "";
00254                         fFunc = 1;
00255                     }
00256                 }
00257                 break;
00258 
00259             case ')'    :
00260                 if(!fParam && !fComent)
00261                 {
00262                     if(!fFunc)
00263                     {
00264                         fQuit = 1;
00265                         break;
00266                     }
00267 
00268                     if(Params.Params.size() != Functions[NoFunc]->NbParam)
00269                     {
00270                         LogError("Parameter count\n");
00271                         CERROR = ERROR_C_PARAMETER;
00272                         break;
00273                     }
00274 
00275                     Out = (String)Functions[NoFunc]->Function(Params);
00276                     fFunc = 0;
00277                 }
00278                 break;
00279 
00280             default     :
00281                 if(!fComent)
00282                 {
00283                     if(fParam)
00284                         Name += *pIn;
00285                     else
00286                     {
00287                         if(fFunc)
00288                         {
00289                             if(IsAlphaNumCar(*pIn))
00290                             {
00291                                 Temp = pIn;
00292                                 Name = Parse(Temp);
00293                                 Params.Params.push_back(Name);
00294                                 Name = "";
00295                             }
00296                         }
00297                         else
00298                             Name += *pIn;
00299                     }
00300                 }
00301                 break;
00302         }//switch
00303 
00304         if(!fQuit)
00305         {
00306             pIn++;
00307             NoCar++;
00308         }
00309     }
00310     while(*pIn && !CERROR && !fQuit);
00311 
00312     PERROR
00313 
00314     return Out;
00315 }

Généré le Thu Jan 24 12:36:04 2008 pour A.I.F. par  doxygen 1.3.9.1