00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef _WIN32
00023 #pragma warning( disable : 4786 )
00024 #endif
00025
00026 #include <iostream>
00027 #include <strstream>
00028 #include <fstream>
00029 #include <string>
00030 #include <vector>
00031
00032 #include "PropertyCompiler.h"
00033 #include "GaudiKernel/xtoa.h"
00034 #include "GaudiKernel/Property.h"
00035
00036 #ifdef WIN32
00037 static const bool win_32=true;
00038 #else
00039 static const bool win_32=false;
00040 #endif
00041
00042
00043
00048 PropertyCompiler::PropertyCompiler(std::string sourcefile, MsgStream& my_log, JobOptionsCatalogue& my_Cat, PropertyCompiler* parent)
00049 : m_log(&my_log), m_Cat(&my_Cat)
00050 {
00051 if ( 0 != parent ) {
00052 includeFiles = parent->includeFiles;
00053 unitsDefined = parent->unitsDefined;
00054 units = parent->units;
00055 hasParent = true;
00056 }
00057 else {
00058 includeFiles = new std::vector <std::string>();
00059 units = new UnitsExtension();
00060 unitsDefined = false;
00061 hasParent = false;
00062 }
00063
00064
00065 sourcefile=resolveEnv(sourcefile);
00074
00075 m_errorCount=0;m_warningCount=0;
00076 m_srcName=sourcefile;
00077 m_sy=BOFSy;
00078
00079 m_error=false;
00080
00081
00082 m_in=new std::ifstream(sourcefile.c_str());
00083 if (m_in->fail())
00084 {
00085 *m_log << endreq << MSG::ERROR << "Error #001: Specified property-file " << sourcefile
00086 << " does not exists or can not be opened! " << endreq;
00087 m_errorCount++;
00088 return;
00089 }
00090
00091 for(std::vector<std::string>::iterator i = includeFiles->begin(); i != includeFiles->end(); i++ ) {
00092 if (sourcefile == *i) {
00093 *m_log << endreq << MSG::WARNING << "Warning #001: Specified property-file "
00094 << sourcefile << " was already included by another property-file! " << endreq;
00095 m_warningCount++;
00096 return;
00097 }
00098 }
00099 includeFiles->push_back(sourcefile);
00100 }
00101
00102
00105 PropertyCompiler::~PropertyCompiler()
00106 {
00107 if ( !hasParent ) {
00108 delete includeFiles;
00109 delete units;
00110 }
00111 units = 0;
00112 includeFiles = 0;
00113 m_in->close();
00114 }
00115
00118 std::string PropertyCompiler::resolveEnv(const std::string& sourcefile) {
00119 std::string originalName = sourcefile;
00120 std::string environmentVar="";
00121 std::string resolvedFile ="";
00122 bool inEnvironmentVar=false;
00123 bool unixStyle =false;
00124 unsigned int i;
00125
00126
00127
00128 for (i=0;i<sourcefile.length();i++) {
00129 if (sourcefile[i]=='$') {
00130 inEnvironmentVar = true;
00131 unixStyle = true;
00132 }
00133 else if (sourcefile[i]=='%') {
00134 inEnvironmentVar = (!inEnvironmentVar);
00135 unixStyle = false;
00136 }
00137 else if (inEnvironmentVar) {
00138 if ((sourcefile[i]=='/') || (sourcefile[i]=='\\')) {
00139 if (unixStyle)
00140 inEnvironmentVar=false;
00141
00142 }
00143 if (inEnvironmentVar)
00144 environmentVar=environmentVar+sourcefile[i];
00145 }
00146 else {
00147 resolvedFile = resolvedFile + sourcefile[i];
00148 }
00149
00150 if ((! inEnvironmentVar) && (environmentVar!="")) {
00151 char* resFile;
00152 resFile = ::getenv(environmentVar.c_str());
00153 if (resFile==0) {
00154 return originalName;
00155 }
00156 else {
00157 resolvedFile=resolvedFile + resFile;
00158 }
00159 if (unixStyle) {
00160 resolvedFile=resolvedFile+'/';
00161 unixStyle=false;
00162 }
00163 environmentVar="";
00164 }
00165 }
00166
00167 if ((inEnvironmentVar) && (environmentVar!="") && (unixStyle)) {
00168
00169 char* resFile;
00170
00171 resFile = getenv(environmentVar.c_str());
00172 if (resFile==0)
00173 return originalName;
00174 else
00175 resolvedFile=resolvedFile + resFile;
00176
00177 environmentVar="";
00178 unixStyle=false;
00179 inEnvironmentVar=false;
00180 }
00181
00182 if (inEnvironmentVar)
00183
00184 return originalName;
00185
00186 return resolvedFile;
00187 }
00188
00189
00192 void PropertyCompiler::newCh()
00193 {
00194 char readedSrcChar='\0';
00195
00196 if (m_cnr < m_srcLine.length())
00197 {
00198 m_cnr=m_cnr+1;
00199 m_ch=m_srcLine[m_cnr-1];
00200 }
00201 else
00202 {
00203 if (m_compiledLine=="")
00204 m_compiledLine='\n'+m_srcLine;
00205 else
00206 m_compiledLine=m_compiledLine+'\n'+m_srcLine;
00207
00208 if (! m_in->eof())
00209 {
00210 m_srcLine="";
00211 while ((readedSrcChar != '\n') && (! m_in->eof())) {
00212 readedSrcChar='\0';
00213 m_in->get(readedSrcChar);
00214 if ((readedSrcChar != '\n') && (! m_in->eof()))
00215 m_srcLine=m_srcLine+readedSrcChar;
00216 }
00217 m_lnr=m_lnr+1;
00218 m_cnr=0;
00219 m_ch='\n';
00220 }
00221 else
00222 {
00223 m_ch=0;
00224 }
00225 }
00226 }
00227
00228
00232 std::string PropertyCompiler::newSy() {
00233 if (m_sy==noSy)
00234 return "";
00235
00236 std::string numberStr="";
00237 std::string stringStr="";
00238 std::string identifierStr="";
00239
00240
00241 m_tokenlnr=m_lnr;
00242 m_tokencnr=m_cnr+1;
00243
00244 while ((m_ch==' ') || (m_ch==9) || (m_ch=='\n') || (m_ch=='\r'))
00245 {
00246 newCh();
00247 }
00248
00249 if (m_ch=='/')
00250 {
00251 char oldCh=' ';
00252 int inComment=0;
00253
00254
00255
00256 newCh();
00257 if (m_ch=='*')
00258 {
00259 inComment=1;
00260 newCh();
00261 }
00262 else if (m_ch=='/')
00263 {
00264 inComment=2;
00265 newCh();
00266 }
00267
00268 while (inComment != 0)
00269 {
00270
00271 if (m_ch==0)
00272 {
00273 inComment=0;
00274 m_sy=EOFSy;
00275 return "";
00276 }
00277
00278
00279 if ((inComment==1) && (oldCh=='*') && (m_ch=='/'))
00280 {
00281 inComment=0;
00282 }
00283 else if ((inComment==2) && (m_ch=='\n'))
00284 {
00285 inComment=0;
00286 }
00287 oldCh=m_ch;
00288 newCh();
00289 }
00290 return newSy();
00291 }
00292
00293 if (m_ch==0)
00294 {
00295 m_sy=EOFSy;
00296 }
00297 else if (m_ch=='=')
00298 {
00299 m_sy=assignSy;
00300 newCh();
00301 }
00302 else if (m_ch==';')
00303 {
00304 m_sy=semicolonSy;
00305 newCh();
00306 }
00307 else if (m_ch==',')
00308 {
00309 m_sy=commaSy;
00310 newCh();
00311 }
00312 else if (m_ch=='-')
00313 {
00314 m_sy=minusSy;
00315 newCh();
00316 }
00317 else if (m_ch=='{')
00318 {
00319 m_sy=vectorStartSy;
00320 newCh();
00321 }
00322 else if (m_ch=='+')
00323 {
00324 newCh();
00325 if (m_ch=='=')
00326 {
00327 m_sy=appendSy;
00328 newCh();
00329 }
00330 else
00331 m_sy=plusSy;
00332 }
00333 else if (m_ch=='}')
00334 {
00335 m_sy=vectorEndSy;
00336 newCh();
00337 }
00338 else if (m_ch=='"')
00339 {
00340 m_sy=stringSy;
00341 newCh();
00342 while (m_ch!='"')
00343 {
00344 stringStr += m_ch;
00345 newCh();
00346 while (m_ch=='\n')
00347 newCh();
00348
00349 if (m_ch==0)
00350 {
00351 *m_log << endreq << MSG::ERROR << "Error #006 in line " << m_tokenlnr
00352 << " at column " << m_tokencnr-1 << ": String not terminated by \" " << endreq;
00353 m_errorCount++;
00354 m_error=true;
00355 m_ch='"';
00356 m_sy=EOFSy;
00357 }
00358 }
00359 newCh();
00360 return stringStr;
00361 }
00362 else if ((m_ch>='0') && (m_ch<='9'))
00363 {
00364 m_sy=numberSy;
00365 while ((m_ch>='0') && (m_ch<='9'))
00366 {
00367 numberStr=numberStr+m_ch;
00368 newCh();
00369 }
00370 return numberStr;
00371 }
00372 else if (m_ch=='.')
00373 {
00374 m_sy=dotSy;
00375 newCh();
00376 }
00377 else if ( ((m_ch>='A') && (m_ch<='Z')) ||
00378 ((m_ch>='_') && (m_ch<='z')) )
00379 {
00380 m_sy=identifierSy;
00381 while (((m_ch>='0') && (m_ch<='9')) || ((m_ch>='A') && (m_ch<='Z')) || ((m_ch>='_') && (m_ch<='z')))
00382 {
00383 identifierStr=identifierStr+m_ch;
00384 newCh();
00385 }
00386
00387 if ((identifierStr=="true") || (identifierStr=="false"))
00388 {
00389 m_sy=booleanSy;
00390 }
00391 return identifierStr;
00392 }
00393 else if (m_ch=='#')
00394 {
00395 newCh();
00396 while (((m_ch>='0') && (m_ch<='9')) || ((m_ch>='A') && (m_ch<='Z')) || ((m_ch>='_') && (m_ch<='z')))
00397 {
00398 identifierStr=identifierStr+m_ch;
00399 newCh();
00400 }
00401 if (identifierStr=="include")
00402 m_sy=includeSy;
00403 else if (identifierStr=="ifdef")
00404 m_sy=ifDefSy;
00405 else if (identifierStr=="ifndef")
00406 m_sy=ifNDefSy;
00407 else if (identifierStr=="endif")
00408 m_sy=endIfSy;
00409 else if (identifierStr=="else")
00410 m_sy=elseSy;
00411 else if (identifierStr=="units")
00412 m_sy=unitsSy;
00413 else
00414 m_sy=noSy;
00415 }
00416 else if (m_ch=='$') {
00417 identifierStr = m_ch;
00418 newCh();
00419 while (((m_ch>='0') && (m_ch<='9')) || ((m_ch>='A') && (m_ch<='Z')) || ((m_ch>='_') && (m_ch<='z'))) {
00420 identifierStr += m_ch;
00421 newCh();
00422 }
00423 m_sy = envSy;
00424 return identifierStr;
00425 }
00426 else if (m_ch=='@') {
00427 identifierStr = m_ch;
00428 newCh();
00429 while (((m_ch>='0') && (m_ch<='9')) || ((m_ch>='A') && (m_ch<='Z')) || ((m_ch>='_') && (m_ch<='z')) || m_ch=='.' ) {
00430 identifierStr += m_ch;
00431 newCh();
00432 }
00433 m_sy = propSy;
00434 return identifierStr;
00435 }
00436 else {
00437 m_sy=noSy;
00438 }
00439
00440 return "";
00441 }
00442
00443
00444
00448 bool PropertyCompiler::isNextEntryPoint()
00449 {
00450 if (m_sy==semicolonSy)
00451 {
00452 newSy();
00453 return true;
00454 }
00455 return false;
00456 }
00457
00458
00462 PropertyCompiler::Symbols PropertyCompiler::getValueType(std::string& valueStr) {
00463 Symbols value=noSy;
00464 std::string returnValue;
00465 bool negation=false;
00466
00467 if (m_sy==stringSy) {
00468 newSy();
00469 value=stringSy;
00470 }
00471 else if (m_sy == envSy ) {
00472 newSy();
00473 value = envSy;
00474 }
00475 else if (m_sy == propSy ) {
00476 newSy();
00477 value = propSy;
00478 }
00479 else if (m_sy==booleanSy) {
00480 newSy();
00481 value=booleanSy;
00482 }
00483 else if (m_sy==minusSy) {
00484 returnValue=newSy();
00485 if (m_sy!=numberSy)
00486 m_sy=noSy;
00487 else {
00488 negation=true;
00489
00490 valueStr='-'+returnValue;
00491 }
00492 }
00493
00494 if (m_sy==numberSy) {
00495 returnValue=newSy();
00496 value=numberSy;
00497 if (m_sy==dotSy) {
00498
00499 returnValue=newSy();
00500 value=realSy;
00501 if (m_sy==numberSy) {
00502 valueStr=valueStr+"."+returnValue;
00503 returnValue=newSy();
00504 }
00505 }
00506
00507
00508 if ((m_sy==identifierSy) && ((returnValue=="e") || (returnValue=="E")) ) {
00509
00510 returnValue=newSy();
00511 if (m_sy==numberSy) {
00512 valueStr=valueStr+"e"+returnValue;
00513 newSy();
00514 }
00515 else {
00516 m_sy=noSy;
00517 }
00518 }
00519
00520
00521
00522 else if (m_sy==identifierSy) {
00523
00524 if (units->existsUnit(returnValue)) {
00525 if (value==numberSy) {
00526 int calculatedValue = atoi(valueStr.c_str());
00527 calculatedValue = (int)(calculatedValue * units->getFactor(returnValue));
00528 std::strstream valstr;
00529 valstr << calculatedValue << std::ends;
00530 valueStr = valstr.str( );
00531 }
00532 else if (value==realSy) {
00533 double calculatedValue = atof(valueStr.c_str());
00534 calculatedValue = calculatedValue * units->getFactor(returnValue);
00535 int decnr, sign;
00536 char* buffer = _ecvt(calculatedValue,40,&decnr,&sign);
00537 valueStr = buffer;
00538 valueStr = valueStr.insert(decnr,".");
00539 }
00540 else {
00541 m_sy=noSy;
00542 }
00543 newSy();
00544 }
00545 else {
00546 m_sy=noSy;
00547 }
00548 }
00549 }
00550
00551 else if (m_sy==dotSy) {
00552 returnValue=newSy();
00553 if (m_sy==numberSy) {
00554 value=realSy;
00555 valueStr=valueStr+"."+returnValue;
00556 returnValue=newSy();
00557
00558
00559 if ((m_sy==identifierSy) && ((returnValue=="e") || (returnValue=="E")) ) {
00560
00561 returnValue=newSy();
00562 if (m_sy==numberSy) {
00563 valueStr=valueStr+"e"+returnValue;
00564 newSy();
00565 }
00566 else {
00567 m_sy=noSy;
00568 }
00569 }
00570
00571
00572 else if (m_sy==identifierSy) {
00573
00574 if (units->existsUnit(returnValue)) {
00575 if (value==numberSy) {
00576 int calculatedValue = atoi(valueStr.c_str());
00577 calculatedValue = (int)(calculatedValue * units->getFactor(returnValue));
00578 std::strstream valstr;
00579 valstr << calculatedValue << std::ends;
00580 valueStr = valstr.str( );
00581 }
00582 else if (value==realSy) {
00583 double calculatedValue = atof(valueStr.c_str());
00584 calculatedValue = calculatedValue * units->getFactor(returnValue);
00585 int decnr, sign;
00586 char* buffer = _ecvt(calculatedValue,40,&decnr,&sign);
00587 valueStr = buffer;
00588 valueStr = valueStr.insert(decnr,".");
00589 }
00590 else {
00591 m_sy=noSy;
00592 }
00593 newSy();
00594 }
00595 else {
00596 m_sy=noSy;
00597 }
00598 }
00599 }
00600 else
00601 value=noSy;
00602 }
00603
00604 return value;
00605 }
00606
00607 void PropertyCompiler::ignorePlatformDependendLines() {
00608 while ((m_sy!=endIfSy) && (m_sy!=elseSy) && (m_sy!=EOFSy))
00609 newSy();
00610 }
00611
00612 void PropertyCompiler::getEntryPointOfDependendLines() {
00613 while ((m_sy!=endIfSy) && (m_sy!=EOFSy))
00614 newSy();
00615 }
00616
00617
00621 StatusCode PropertyCompiler::checkSyntax() {
00622 std::string returnValue;
00623 std::string objName;
00624 std::string propName;
00625 std::string valueStr;
00626 std::string newName;
00627 Symbols oldType;
00628 Symbols valueType;
00629 Operations operation;
00630 bool elsePathValid=false;
00631
00632
00633
00634 objName=newSy();
00635
00636 while (m_sy != EOFSy ) {
00637
00638 if ((! m_error) && (m_compiledLine!="")) {
00639 if (m_compiledLine.find(";",0)== std::string::npos)
00640 {
00641 *m_log << MSG::INFO << m_compiledLine;
00642 m_compiledLine="";
00643 }
00644 else {
00645 std::string output=m_compiledLine.substr(0, m_compiledLine.find_last_of(";",0));
00646 *m_log << MSG::INFO << output;
00647
00648 m_compiledLine.erase(0, m_compiledLine.find_last_of(";",0));
00649 }
00650 }
00651
00652
00653 if (m_error) {
00654
00655 if ( (m_compiledLine.find("//",0)!=m_compiledLine.npos) &&
00656 (m_compiledLine.find("//",0) < (m_compiledLine.find(";",0))) )
00657 {
00658 m_compiledLine.erase(0, m_compiledLine.find("//",0));
00659 }
00660 else if ( (m_compiledLine.find("/*",0)!=m_compiledLine.npos) &&
00661 (m_compiledLine.find("/*",0) < (m_compiledLine.find(";",0))) )
00662 {
00663 m_compiledLine.erase(0, m_compiledLine.find("/*",0));
00664 }
00665 else
00666 {
00667 if (m_compiledLine.find(";",0)==m_compiledLine.npos)
00668 m_compiledLine="";
00669 else
00670 {
00671 m_compiledLine.erase(0, m_compiledLine.find(";",0)+1);
00672 }
00673 }
00674 }
00675
00676 m_error=false;
00677
00678
00679
00680 if ((m_sy!=identifierSy) && (m_sy!=includeSy) && (m_sy!=ifDefSy) &&
00681 (m_sy!=ifNDefSy) && (m_sy!=endIfSy) && (m_sy!=elseSy) && m_sy!=unitsSy)
00682 {
00683 *m_log << endreq << MSG::ERROR << "Error #002 in line " << m_tokenlnr
00684 << " at column " << m_tokencnr-1 << ": Object expected!" << endreq;
00685 m_errorCount++;
00686 m_error=true;
00687 objName="";
00688 }
00689
00690
00691 if (m_sy==unitsSy) {
00692 returnValue = newSy();
00693 if (m_sy != stringSy) {
00694 *m_log << endreq << MSG::ERROR << "Error #020 in line " << m_tokenlnr
00695 << " at column " << m_tokencnr-1 << ": syntax error: #units \"filename\"!" << endreq;
00696 m_errorCount++;
00697 m_error=true;
00698 }
00699
00700 m_compiledLine="";
00701
00702 objName = newSy();
00703 if (m_sy==semicolonSy) {
00704 *m_log << endreq << MSG::ERROR << "Error #008 in line " << m_tokenlnr << " at column " << m_tokencnr-1
00705 << ": syntax error: #units doesn't end with a ';'!" << endreq;
00706 m_errorCount++;
00707 m_error=true;
00708 newSy();
00709 }
00710
00711 if (unitsDefined==true) {
00712 *m_log << endreq << MSG::WARNING << "Warning #021 in line " << m_tokenlnr
00713 << " at column " << m_tokencnr-1 << ": An unit-definition file was already included before! Definition was skipped!" << endreq;
00714 m_warningCount++;
00715
00716 }
00717 else {
00718
00719 returnValue = resolveEnv(returnValue);
00720 if (units->getUnits(returnValue)) {
00721 unitsDefined = true;
00722 }
00723 else {
00724 *m_log << endreq << MSG::ERROR << "Error #022 in line " << m_tokenlnr << " at column " << m_tokencnr-1
00725 << ": cannot open unit-definition file " << returnValue << endreq;
00726 m_errorCount++;
00727 m_error=true;
00728 }
00729 }
00730 continue;
00731 }
00732
00733
00734 if (m_sy==includeSy) {
00735 returnValue=newSy();
00736 if (m_sy!=stringSy) {
00737 *m_log << endreq << MSG::ERROR << "Error #007 in line " << m_tokenlnr
00738 << " at column " << m_tokencnr-1 << ": syntax error: #include \"filename\"!" <<endreq;
00739 m_errorCount++;
00740 m_error=true;
00741 }
00742
00743 m_compiledLine="";
00744
00745 objName=newSy();
00746 if (m_sy==semicolonSy) {
00747 *m_log << endreq << MSG::ERROR << "Error #008 in line " << m_tokenlnr << " at column " << m_tokencnr-1
00748 << ": syntax error: #include doesn't end with a ';'!" << endreq;
00749 m_errorCount++;
00750 m_error=true;
00751 newSy();
00752 }
00753
00754
00755
00756 if (! m_error) {
00757 *m_log << MSG::INFO << "// --> Including file " << returnValue << "\n";
00758 PropertyCompiler *pc=new PropertyCompiler(returnValue, *m_log, *m_Cat, this);
00759 if (! pc->startCompiler().isSuccess()) {
00760
00761 m_errorCount++;
00762 m_error=true;
00763 }
00764
00765
00766
00767
00768
00769
00770
00771 *m_log << MSG::INFO << "// <-- End of including file " << returnValue << "\n";
00772 delete pc;
00773 }
00774
00775 continue;
00776 }
00777
00778
00779 if (m_sy==ifDefSy) {
00780 returnValue=newSy();
00781
00782 if (m_sy!=identifierSy) {
00783 *m_log << endreq << MSG::ERROR << "Error #017 in line " << m_tokenlnr
00784 << " at column " << m_tokencnr-1 << ": syntax error: #ifdef not followed by an identifier!" <<endreq;
00785 getEntryPointOfDependendLines();
00786 m_errorCount++;
00787 m_error=true;
00788 }
00789
00790 if (returnValue!="WIN32") {
00791 *m_log << endreq << MSG::ERROR << "Error #018 in line " << m_tokenlnr
00792 << " at column " << m_tokencnr-1 << ": syntax error: identifier in #ifdef not known!" <<endreq;
00793 getEntryPointOfDependendLines();
00794 m_errorCount++;
00795 m_error=true;
00796 }
00797
00798 if ((returnValue=="WIN32") && (! win_32)) {
00799 if (! m_error) {
00800 ignorePlatformDependendLines();
00801 elsePathValid=true;
00802 }
00803 }
00804 m_compiledLine="";
00805
00806 objName=newSy();
00807 if (m_sy==semicolonSy) {
00808 *m_log << endreq << MSG::ERROR << "Error #019 in line " << m_tokenlnr << " at column " << m_tokencnr-1
00809 << ": syntax error: #ifdef doesn't end with a ';'!" << endreq;
00810 m_errorCount++;
00811 m_error=true;
00812 newSy();
00813 }
00814 continue;
00815 }
00816
00817
00818 if (m_sy==ifNDefSy) {
00819 returnValue=newSy();
00820
00821 if (m_sy!=identifierSy) {
00822 *m_log << endreq << MSG::ERROR << "Error #017 in line " << m_tokenlnr
00823 << " at column " << m_tokencnr-1 << ": syntax error: #ifndef not followed by an identifier!" <<endreq;
00824 getEntryPointOfDependendLines();
00825 m_errorCount++;
00826 m_error=true;
00827 }
00828
00829 if (returnValue!="WIN32") {
00830 *m_log << endreq << MSG::ERROR << "Error #018 in line " << m_tokenlnr
00831 << " at column " << m_tokencnr-1 << ": syntax error: identifier in #ifndef not known!" <<endreq;
00832 getEntryPointOfDependendLines();
00833 m_errorCount++;
00834 m_error=true;
00835 }
00836
00837 if ((returnValue=="WIN32") && (win_32)) {
00838 if (! m_error) {
00839 ignorePlatformDependendLines();
00840 elsePathValid=true;
00841 }
00842 }
00843 m_compiledLine="";
00844
00845 objName=newSy();
00846 if (m_sy==semicolonSy) {
00847 *m_log << endreq << MSG::ERROR << "Error #019 in line " << m_tokenlnr << " at column " << m_tokencnr-1
00848 << ": syntax error: #ifndef doesn't end with a ';'!" << endreq;
00849 m_errorCount++;
00850 m_error=true;
00851 newSy();
00852 }
00853 continue;
00854 }
00855
00856
00857 if ( m_sy == elseSy ) {
00858 objName=newSy();
00859 if (m_sy==semicolonSy) {
00860 *m_log << endreq << MSG::ERROR << "Error #019 in line " << m_tokenlnr << " at column " << m_tokencnr-1
00861 << ": syntax error: #else doesn't end with a ';'!" << endreq;
00862 m_errorCount++;
00863 m_error=true;
00864 newSy();
00865 }
00866
00867 if (! elsePathValid) {
00868 if (! m_error) {
00869 ignorePlatformDependendLines();
00870 }
00871 }
00872 m_compiledLine="";
00873
00874 elsePathValid=false;
00875 continue;
00876 }
00877
00878
00879 if ( m_sy==endIfSy) {
00880 m_compiledLine="";
00881
00882 objName=newSy();
00883 if (m_sy==semicolonSy) {
00884 *m_log << endreq << MSG::ERROR << "Error #019 in line " << m_tokenlnr << " at column " << m_tokencnr-1
00885 << ": syntax error: #endif doesn't end with a ';'!" << endreq;
00886 m_errorCount++;
00887 m_error=true;
00888 newSy();
00889 }
00890 continue;
00891 }
00892
00893 newName=objName;
00894 objName="";
00895
00896 while (m_sy==identifierSy) {
00897 objName=objName+newName;
00898 newSy();
00899 if (m_sy==semicolonSy)
00900 break;
00901
00902 if (m_sy==dotSy) {
00903 newName="."+newSy();
00904 if (m_sy==semicolonSy)
00905 break;
00906 }
00907 }
00908
00909 if (objName.find(".")==objName.npos)
00910 {
00911 *m_log << endreq << MSG::ERROR << "Error #003 in line " << m_tokenlnr << " at column " << m_tokencnr-1
00912 << ": Object and Property must be divided by a '.'!" << endreq;
00913 m_errorCount++;
00914 m_error=true;
00915 }
00916 if (isNextEntryPoint())
00917 continue;
00918
00919 if (objName!="")
00920 objName.erase(objName.find_last_of("."), objName.length());
00921 newName.erase(0,1);
00922 propName=newName;
00923
00924 operation=noOperation;
00925 if (m_sy==assignSy)
00926 operation=assign;
00927 else if (m_sy==appendSy)
00928 operation=append;
00929
00930 if (operation==noOperation) {
00931 *m_log << endreq << MSG::ERROR << "Error #005 in line " << m_tokenlnr << " at column " << m_tokencnr-1
00932 << ": syntax error: missing operator '=' or '+='!" << endreq;
00933 m_errorCount++;
00934 m_error=true;
00935 }
00936
00937 returnValue=newSy();
00938 if (isNextEntryPoint())
00939 continue;
00940
00941
00942
00943
00944
00945 std::vector<std::string> propValues;
00946 bool isArrayProp = false;
00947 if (m_sy==vectorStartSy) {
00948 returnValue = newSy();
00949 returnValue = resolveEnv(returnValue);
00950 valueType = getValueType(returnValue);
00951 oldType = valueType;
00952 isArrayProp = true;
00953 if ( valueType == stringSy ) {
00954 propValues.push_back("\""+returnValue+"\"");
00955 }
00956 else if (valueType == booleanSy) {
00957 propValues.push_back((::toupper(returnValue[0]) == 'T' || returnValue[0] == '1') ? "1" : "0" );
00958 }
00959 else if (valueType!=noSy) {
00960 propValues.push_back(returnValue);
00961 }
00962 if (m_sy==commaSy) {
00963 while ((m_sy!=identifierSy) && (m_sy!=EOFSy) && (m_sy!=semicolonSy) && (m_sy!=vectorEndSy)) {
00964 returnValue = newSy();
00965 returnValue = resolveEnv(returnValue);
00966 valueType=getValueType(returnValue);
00967 if ( valueType == stringSy ) {
00968 propValues.push_back("\""+returnValue+"\"");
00969 }
00970 else if (valueType == booleanSy) {
00971 propValues.push_back((::toupper(returnValue[0]) == 'T' || returnValue[0] == '1') ? "1" : "0" );
00972 }
00973 else {
00974 propValues.push_back(returnValue);
00975 }
00976 if ((m_sy!=commaSy) && (m_sy!=identifierSy) && (m_sy!=EOFSy) && (m_sy!=semicolonSy) && (m_sy!=vectorEndSy)) {
00977 *m_log << endreq << MSG::ERROR << "Error #009 in line " << m_tokenlnr << " at column "
00978 << m_tokencnr << ": syntax error: Values in vector must be sperated with ','!" << endreq;
00979 m_errorCount++;
00980 m_error=true;
00981 }
00982 }
00983 }
00984 if (m_sy!=vectorEndSy) {
00985 *m_log << endreq << MSG::ERROR << "Error #010 in line " << m_tokenlnr << " at column "
00986 << m_tokencnr << ": syntax error: Vector must end with a closing braket '}'!" << endreq;
00987 m_errorCount++;
00988 m_error=true;
00989 }
00990 newSy();
00991 }
00992 else {
00993 returnValue = resolveEnv(returnValue);
00994 valueType=getValueType(returnValue);
00995 oldType=valueType;
00996
00997 if (valueType==noSy) {
00998 *m_log << endreq << MSG::ERROR << "Error #015 in line " << m_tokenlnr << " at column "
00999 << m_tokencnr << ": Value(s) expected!" << endreq;
01000 m_errorCount++;
01001 m_error=true;
01002 newSy();
01003 returnValue="";
01004 }
01005 else if ( valueType == stringSy ) {
01006 propValues.push_back("\""+returnValue+"\"");
01007 }
01008 else if (valueType == booleanSy) {
01009 propValues.push_back((::toupper(returnValue[0]) == 'T' || returnValue[0] == '1') ? "1" : "0" );
01010 }
01011 else {
01012 propValues.push_back(returnValue);
01013 }
01014 }
01015
01016 if (m_sy!=semicolonSy) {
01017 *m_log << endreq << MSG::ERROR << "Error #011 in line " << m_tokenlnr << " at column "
01018 << m_tokencnr << ": syntax error: missing ';'!" << endreq;
01019 m_errorCount++;
01020 m_error=true;
01021 }
01022
01023
01024
01025 if (!m_error) {
01026
01027
01028 if ( propValues.size() == 0 ) {
01029 switch ( operation ) {
01030 case assign:
01031 operation = clear;
01032 break;
01033 case append:
01034 operation = noOperation;
01035 break;
01036 default:
01037 break;
01038 }
01039 }
01040 std::vector<const Property*>* myOpts = 0;
01041 switch( operation ) {
01042 case append:
01043 case assign:
01044 case clear:
01045 if ( m_Cat->optionsOf(objName, myOpts).isSuccess() ) {
01046 std::vector<const Property*>::iterator itr;
01047 for ( itr=myOpts->begin(); itr!=myOpts->end(); itr++ ) {
01048 if ((*itr)->name() == propName ) {
01049 switch ( operation ) {
01050 case append: {
01051 const StringArrayProperty* sap =
01052 dynamic_cast<const StringArrayProperty*> (*itr);
01053 if ( sap != 0 ) {
01054 std::vector<std::string> res = sap->value();
01055 for ( unsigned int it = 0; it < propValues.size(); it++ )
01056 res.push_back(propValues[it]);
01057 propValues = res;
01058 }
01059 }
01060 break;
01061 default:
01062 break;
01063 }
01064 myOpts->erase(itr);
01065 break;
01066 }
01067 }
01068 }
01069 if ( isArrayProp ) {
01070 m_Cat->addOption( objName, new StringArrayProperty(propName, propValues));
01071 }
01072 else {
01073 m_Cat->addOption( objName, new StringProperty(propName, propValues[0]));
01074 }
01075 break;
01076 default:
01077 break;
01078 }
01079 }
01080
01081
01082 objName=newSy();
01083
01084 if (isNextEntryPoint())
01085 continue;
01086
01087 if (m_sy==noSy) {
01088 m_error=true;
01089 m_errorCount++;
01090 *m_log << endreq << MSG::ERROR << "Error #000 in line " << m_tokenlnr << " at column " << m_tokencnr
01091 << ": \nFatal compiler error!"
01092 << "\nThis Error can have several reasons:\n"
01093 << "* The job-option-file contains invalid characters\n"
01094 << "* The job-option-file is not valid\n"
01095 << "* The property-compiler could not recover from previous error\n"
01096 << "* Memory or Disk-problem\n"
01097 << "\n\nCompiler will now try to recover.\n"
01098 << "WARNING: ONE OR MORE LINES ARE IGNORED AND NOT PRINTED OUT BY THE COMPILER.\n"
01099 << "PLEASE CHECK MANUALLY STATEMENTS BEFORE AND AFTER ERROR-POSITION!!!\n\n" << endreq;
01100
01101
01102 m_sy=BOFSy;
01103 newCh();
01104
01105 objName=newSy();
01106 while ( (m_sy!=semicolonSy) && (m_sy!=EOFSy) ) {
01107 newSy();
01108 if (m_sy==noSy) {
01109 m_sy=BOFSy;
01110 newCh();
01111 }
01112 }
01113 if (m_sy==EOFSy)
01114 return StatusCode::FAILURE;
01115
01116 m_compiledLine="";
01117 objName=newSy();
01118 continue;
01119 }
01120
01121 }
01122
01123
01124
01125 if ((! m_error) && (m_compiledLine!="")) {
01126 *m_log << MSG::INFO << m_compiledLine << "\n";
01127 m_compiledLine="";
01128 }
01129
01130 if (m_error)
01131 m_compiledLine="";
01132
01133
01134 if (m_errorCount != 0) {
01135 *m_log << MSG::INFO << m_errorCount << " error(s) in file " << m_srcName << endreq;
01136 return StatusCode::FAILURE;
01137 }
01138
01139 return StatusCode::SUCCESS;
01140 }
01141
01142
01143
01144
01148 StatusCode PropertyCompiler::startCompiler()
01149 {
01150 if ((m_errorCount!=0) || (m_warningCount!=0))
01151 return StatusCode::FAILURE;
01152
01153
01154 m_srcLine="";
01155 m_compiledLine="";
01156 m_lnr=0;
01157 m_cnr=0;
01158 m_errorCount=0;
01159 newCh();
01160 StatusCode result=checkSyntax();
01161 return result;
01162 }
01163