00001
00002
00003
00004
00005
00006
00007
00008
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 '#' :
00189 if(!fParam)
00190 fComent = 1;
00191 else
00192 Name += *pIn;
00193 break;
00194
00195 case '\n' :
00196 fComent = 0;
00197 NoLine++;
00198 NoCar = 0;
00199 break;
00200
00201 case '\0' :
00202 if(fFunc || fParam)
00203 {
00204 LogError("End of file found\n");
00205 CERROR = ERROR_C_SYNTAX;
00206 }
00207 break;
00208
00209 case '\"' :
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 '(' :
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 }
00303
00304 if(!fQuit)
00305 {
00306 pIn++;
00307 NoCar++;
00308 }
00309 }
00310 while(*pIn && !CERROR && !fQuit);
00311
00312 PERROR
00313
00314 return Out;
00315 }