Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cmt_syntax.cxx

Go to the documentation of this file.
00001 //-----------------------------------------------------------
00002 // Copyright Christian Arnault LAL-Orsay CNRS
00003 // arnault@lal.in2p3.fr
00004 // See the complete license in cmt_license.txt "http://www.cecill.info". 
00005 //-----------------------------------------------------------
00006 
00007 #include "cmt_syntax.h"
00008 #include "cmt.h"
00009 #include "cmt_symbol.h"
00010 #include "cmt_constituent.h"
00011 #include "cmt_pattern.h"
00012 #include "cmt_error.h"
00013 #include "cmt_branch.h"
00014 #include "cmt_error.h"
00015 #include "cmt_script.h"
00016 #include "cmt_language.h"
00017 #include "cmt_project.h"
00018 #include "cmt_cmtpath_pattern.h"
00019 
00020 void Kwd::action (const CmtSystem::cmt_string_vector& words,
00021                   Project* project,
00022                   const cmt_string& file_name,
00023                   int line_number)
00024 {
00025 }
00026 
00027 class KwdAction : public Kwd
00028 {
00029 public:
00030   void action (const CmtSystem::cmt_string_vector& words,
00031                Use* use,
00032                const cmt_string& file_name,
00033                int line_number)
00034   {
00035     Symbol::action (words, CommandAction, use);
00036   }
00037 };
00038 
00039 class KwdAlias : public Kwd
00040 {
00041 public:
00042   void action (const CmtSystem::cmt_string_vector& words,
00043                Use* use,
00044                const cmt_string& file_name,
00045                int line_number)
00046   {
00047     Symbol::action (words, CommandAlias, use);
00048   }
00049 };
00050 
00051 class KwdApplication : public Kwd
00052 {
00053 public:
00054   void action (const CmtSystem::cmt_string_vector& words,
00055                Use* use,
00056                const cmt_string& file_name,
00057                int line_number)
00058   {
00059     if (use == &(Use::current ()))
00060       {
00061         Constituent::action (Application, words);
00062       }
00063   }
00064 };
00065 
00066 class KwdApplyPattern : public Kwd
00067 {
00068 public:
00069   void action (const CmtSystem::cmt_string_vector& words,
00070                Use* use,
00071                const cmt_string& file_name,
00072                int line_number)
00073   {
00074     ApplyPattern::action (words, use);
00075   }
00076 };
00077 
00078 class KwdApplyTag : public Kwd
00079 {
00080 public:
00081   void action (const CmtSystem::cmt_string_vector& words,
00082                Use* use,
00083                const cmt_string& file_name,
00084                int line_number)
00085   {
00086     Tag::action_apply (words, use);
00087   }
00088 };
00089 
00090 class KwdAuthor : public Kwd
00091 {
00092 public:
00093   void action (const CmtSystem::cmt_string_vector& words,
00094                Use* use,
00095                const cmt_string& file_name,
00096                int line_number)
00097   {
00098     use->author_action (words);
00099   }
00100 };
00101 
00102 class KwdBranches : public Kwd
00103 {
00104 public:
00105   void action (const CmtSystem::cmt_string_vector& words,
00106                Use* use,
00107                const cmt_string& file_name,
00108                int line_number)
00109   {
00110     if (use == &(Use::current ())) 
00111       {
00112         Branch::action (words);
00113       }
00114   }
00115 };
00116 
00117 class KwdBuildStrategy : public Kwd
00118 {
00119 public:
00120   bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value)
00121   {
00122     bool result = true;
00123 
00124     value = w;
00125 
00126     if (w == "prototypes")
00127       {
00128         strategy = "BuildPrototypes";
00129       }
00130     else if (w == "no_prototypes")
00131       {
00132         strategy = "BuildPrototypes";
00133       }
00134     else if ((w == "with_installarea") || (w == "with_install_area"))
00135       {
00136         value = "with_installarea";
00137         strategy = "InstallArea";
00138       }
00139     else if ((w == "without_installarea") || (w == "without_install_area"))
00140       {
00141         value = "without_installarea";
00142         strategy = "InstallArea";
00143       }
00144     else
00145       {
00146         result = false;
00147       }
00148 
00149     return (result);
00150   }
00151 
00152   void action (const CmtSystem::cmt_string_vector& words,
00153                Use* use,
00154                const cmt_string& file_name,
00155                int line_number)
00156   {
00157     cmt_string cmtpath;
00158     cmt_string offset;
00159 
00160     use->get_cmtpath_and_offset (cmtpath, offset);
00161 
00162     Project* p = Project::find_by_cmtpath (cmtpath);
00163 
00164     for (int i = 1; i < words.size (); i++)
00165       {
00166         const cmt_string& w = words[i];
00167 
00168         cmt_string strategy;
00169         cmt_string value;
00170 
00171         bool in_error = false;
00172 
00173         if (decode (w, strategy, value))
00174           {
00175             if (p != 0) p->set_strategy (strategy, value, use->get_package_name ());
00176           }
00177         else
00178           {
00179             in_error = true;
00180 
00181             CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
00182           }
00183       }
00184   }
00185 
00186   void action (const CmtSystem::cmt_string_vector& words,
00187                Project* project,
00188                const cmt_string& file_name,
00189                int line_number)
00190   {
00191     for (int i = 1; i < words.size (); i++)
00192       {
00193         const cmt_string& w = words[i];
00194 
00195         cmt_string strategy;
00196         cmt_string value;
00197 
00198         bool in_error = false;
00199 
00200         if (decode (w, strategy, value))
00201           {
00202             if (project != 0) project->set_strategy (strategy, value, "");
00203           }
00204         else
00205           {
00206             in_error = true;
00207 
00208             CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
00209           }
00210       }
00211   }
00212 };
00213 
00214 class KwdCleanupScript : public Kwd
00215 {
00216 public:
00217   void action (const CmtSystem::cmt_string_vector& words,
00218                Use* use,
00219                const cmt_string& file_name,
00220                int line_number)
00221   {
00222     Script::action (words, CleanupScript, use);
00223     Symbol::action (words, CommandCleanupScript, use);
00224   }
00225 };
00226 
00227 class KwdCmtPathPattern : public Kwd
00228 {
00229 public:
00230   void action (const CmtSystem::cmt_string_vector& words,
00231                Use* use,
00232                const cmt_string& /*file_name*/,
00233                int /*line_number*/)
00234   {
00235     CmtPathPattern::action (words, use);
00236   }
00237 };
00238 
00239 class KwdContainer : public Kwd
00240 {
00241 public:
00242   void action (const CmtSystem::cmt_string_vector& words,
00243                Use* use,
00244                const cmt_string& file_name,
00245                int line_number)
00246   {
00247   }
00248 
00249   void action (const CmtSystem::cmt_string_vector& words,
00250                Project* project,
00251                const cmt_string& file_name,
00252                int line_number)
00253   {
00254     project->container_action (words[1], words[2]);
00255   }
00256 };
00257 
00258 class KwdDocument : public Kwd
00259 {
00260 public:
00261   void action (const CmtSystem::cmt_string_vector& words,
00262                Use* use,
00263                const cmt_string& file_name,
00264                int line_number)
00265   {
00266     if (use == &(Use::current ()))
00267       {
00268         Constituent::action (Document, words);
00269       }
00270   }
00271 };
00272 
00273 class KwdEndPrivate : public Kwd
00274 {
00275 public:
00276   void action (const CmtSystem::cmt_string_vector& words,
00277                Use* use,
00278                const cmt_string& file_name,
00279                int line_number)
00280   {
00281     if (use != &(Use::current ()))
00282       {
00283         use->pop_scope_section ();
00284       }
00285   }
00286 };
00287 
00288 class KwdEndPublic : public Kwd
00289 {
00290 public:
00291   void action (const CmtSystem::cmt_string_vector& words,
00292                Use* use,
00293                const cmt_string& file_name,
00294                int line_number)
00295   {
00296     if (use != &(Use::current ()))
00297       {
00298         use->pop_scope_section ();
00299       }
00300   }
00301 };
00302 
00303 class KwdIgnorePattern : public Kwd
00304 {
00305 public:
00306   void action (const CmtSystem::cmt_string_vector& words,
00307                Use* use,
00308                const cmt_string& file_name,
00309                int line_number)
00310   {
00311     IgnorePattern::action (words, use);
00312   }
00313 };
00314 
00315 class KwdIncludeDirs : public Kwd
00316 {
00317 public:
00318   void action (const CmtSystem::cmt_string_vector& words,
00319                Use* use,
00320                const cmt_string& file_name,
00321                int line_number)
00322   {
00323     Include::action (words, use);
00324   }
00325 };
00326 
00327 class KwdIncludePath : public Kwd
00328 {
00329 public:
00330   void action (const CmtSystem::cmt_string_vector& words,
00331                Use* use,
00332                const cmt_string& file_name,
00333                int line_number)
00334   {
00335     if (words.size () > 1)
00336       {
00337         use->set_include_path (words[1]);
00338       }
00339   }
00340 };
00341 
00342 class KwdLanguage : public Kwd
00343 {
00344 public:
00345   void action (const CmtSystem::cmt_string_vector& words,
00346                Use* use,
00347                const cmt_string& file_name,
00348                int line_number)
00349   {
00350     Language::action (words);
00351   }
00352 };
00353 
00354 class KwdLibrary : public Kwd
00355 {
00356 public:
00357   void action (const CmtSystem::cmt_string_vector& words,
00358                Use* use,
00359                const cmt_string& file_name,
00360                int line_number)
00361   {
00362     if (use == &(Use::current ()))
00363       {
00364         Constituent::action (Library, words);
00365       }
00366   }
00367 };
00368 
00369 class KwdMacro : public Kwd
00370 {
00371 public:
00372   void action (const CmtSystem::cmt_string_vector& words,
00373                Use* use,
00374                const cmt_string& file_name,
00375                int line_number)
00376   {
00377     Symbol::action (words, CommandMacro, use);
00378   }
00379 };
00380 
00381 class KwdMacroPrepend : public Kwd
00382 {
00383 public:
00384   void action (const CmtSystem::cmt_string_vector& words,
00385                Use* use,
00386                const cmt_string& file_name,
00387                int line_number)
00388   {
00389     Symbol::action (words, CommandMacroPrepend, use);
00390   }
00391 };
00392 
00393 class KwdMacroAppend : public Kwd
00394 {
00395 public:
00396   void action (const CmtSystem::cmt_string_vector& words,
00397                Use* use,
00398                const cmt_string& file_name,
00399                int line_number)
00400   {
00401     Symbol::action (words, CommandMacroAppend, use);
00402   }
00403 };
00404 
00405 class KwdMacroRemove : public Kwd
00406 {
00407 public:
00408   void action (const CmtSystem::cmt_string_vector& words,
00409                Use* use,
00410                const cmt_string& file_name,
00411                int line_number)
00412   {
00413     Symbol::action (words, CommandMacroRemove, use);
00414   }
00415 };
00416 
00417 class KwdMacroRemoveRegexp : public Kwd
00418 {
00419 public:
00420   void action (const CmtSystem::cmt_string_vector& words,
00421                Use* use,
00422                const cmt_string& file_name,
00423                int line_number)
00424   {
00425     Symbol::action (words, CommandMacroRemoveRegexp, use);
00426   }
00427 };
00428 
00429 class KwdMacroRemoveAll : public Kwd
00430 {
00431 public:
00432   void action (const CmtSystem::cmt_string_vector& words,
00433                Use* use,
00434                const cmt_string& file_name,
00435                int line_number)
00436   {
00437     Symbol::action (words, CommandMacroRemoveAll, use);
00438   }
00439 };
00440 
00441 class KwdMacroRemoveAllRegexp : public Kwd
00442 {
00443 public:
00444   void action (const CmtSystem::cmt_string_vector& words,
00445                Use* use,
00446                const cmt_string& file_name,
00447                int line_number)
00448   {
00449     Symbol::action (words, CommandMacroRemoveAllRegexp, use);
00450   }
00451 };
00452 
00453 class KwdMakeFragment : public Kwd
00454 {
00455 public:
00456   void action (const CmtSystem::cmt_string_vector& words,
00457                Use* use,
00458                const cmt_string& file_name,
00459                int line_number)
00460   {
00461     Fragment::action (words, use);
00462   }
00463 };
00464 
00465 class KwdManager : public Kwd
00466 {
00467 public:
00468   void action (const CmtSystem::cmt_string_vector& words,
00469                Use* use,
00470                const cmt_string& file_name,
00471                int line_number)
00472   {
00473     use->manager_action (words);
00474   }
00475 };
00476 
00477 class KwdPackage : public Kwd
00478 {
00479 public:
00480   void action (const CmtSystem::cmt_string_vector& words,
00481                Use* use,
00482                const cmt_string& file_name,
00483                int line_number)
00484   {
00485     /*
00486     if (words.size () > 1)
00487       {
00488         if (use == &(Use::current()))
00489           {
00490             m_current_package = words[1];
00491             build_prefix (m_current_package, m_current_prefix);
00492             
00493             if ((use->get_package_name () != "") &&
00494                 (use->get_package_name () != m_current_package))
00495               {
00496                 if (!m_quiet)
00497                   {
00498                     //  cerr << "#CMT> package name mismatch in requirements of " <<
00499                     //  use->get_package_name () << " " <<
00500                     //  use->version << " line #" << line_number;
00501                     //  cerr << " : " << m_current_package << " versus " <<
00502                     //  use->get_package_name () << endl;
00503                   }
00504               }
00505             
00506             use->set (m_current_package,
00507                       m_current_version,
00508                       m_current_path,
00509                       "",
00510                       "");
00511             
00512             use->change_path (m_current_path);
00513             use->style = m_current_style;
00514           }
00515       }
00516     */
00517   }
00518 };
00519 
00520 class KwdPath : public Kwd
00521 {
00522 public:
00523   void action (const CmtSystem::cmt_string_vector& words,
00524                Use* use,
00525                const cmt_string& file_name,
00526                int line_number)
00527   {
00528     Symbol::action (words, CommandPath, use);
00529   }
00530 };
00531 
00532 class KwdPathAppend : public Kwd
00533 {
00534 public:
00535   void action (const CmtSystem::cmt_string_vector& words,
00536                Use* use,
00537                const cmt_string& file_name,
00538                int line_number)
00539   {
00540     Symbol::action (words, CommandPathAppend, use);
00541   }
00542 };
00543 
00544 class KwdPathPrepend : public Kwd
00545 {
00546 public:
00547   void action (const CmtSystem::cmt_string_vector& words,
00548                Use* use,
00549                const cmt_string& file_name,
00550                int line_number)
00551   {
00552     Symbol::action (words, CommandPathPrepend, use);
00553   }
00554 };
00555 
00556 class KwdPathRemove : public Kwd
00557 {
00558 public:
00559   void action (const CmtSystem::cmt_string_vector& words,
00560                Use* use,
00561                const cmt_string& file_name,
00562                int line_number)
00563   {
00564     Symbol::action (words, CommandPathRemove, use);
00565   }
00566 };
00567 
00568 class KwdPathRemoveRegexp : public Kwd
00569 {
00570 public:
00571   void action (const CmtSystem::cmt_string_vector& words,
00572                Use* use,
00573                const cmt_string& file_name,
00574                int line_number)
00575   {
00576     Symbol::action (words, CommandPathRemoveRegexp, use);
00577   }
00578 };
00579 
00580 class KwdPattern : public Kwd
00581 {
00582 public:
00583   void action (const CmtSystem::cmt_string_vector& words,
00584                Use* use,
00585                const cmt_string& file_name,
00586                int line_number)
00587   {
00588     Pattern::action (words, use);
00589   }
00590 };
00591 
00592 class KwdPrivate : public Kwd
00593 {
00594 public:
00595   void action (const CmtSystem::cmt_string_vector& words,
00596                Use* use,
00597                const cmt_string& file_name,
00598                int line_number)
00599   {
00600     if (use != &(Use::current ()))
00601       {
00602         use->push_scope_section (ScopePrivate);
00603       }
00604   }
00605 };
00606 
00607 class KwdProject : public Kwd
00608 {
00609 public:
00610   void action (const CmtSystem::cmt_string_vector& words,
00611                Use* use,
00612                const cmt_string& file_name,
00613                int line_number)
00614   {
00615   }
00616 
00617   void action (const CmtSystem::cmt_string_vector& words,
00618                Project* project,
00619                const cmt_string& file_name,
00620                int line_number)
00621   {
00622   }
00623 };
00624 
00625 class KwdPublic : public Kwd
00626 {
00627 public:
00628   void action (const CmtSystem::cmt_string_vector& words,
00629                Use* use,
00630                const cmt_string& file_name,
00631                int line_number)
00632   {
00633     if (use != &(Use::current ()))
00634       {
00635         use->push_scope_section (ScopePublic);
00636       }
00637   }
00638 };
00639 
00640 class KwdSet : public Kwd
00641 {
00642 public:
00643   void action (const CmtSystem::cmt_string_vector& words,
00644                Use* use,
00645                const cmt_string& file_name,
00646                int line_number)
00647   {
00648     Symbol::action (words, CommandSet, use);
00649   }
00650 };
00651 
00652 class KwdSetAppend : public Kwd
00653 {
00654 public:
00655   void action (const CmtSystem::cmt_string_vector& words,
00656                Use* use,
00657                const cmt_string& file_name,
00658                int line_number)
00659   {
00660     Symbol::action (words, CommandSetAppend, use);
00661   }
00662 };
00663 
00664 class KwdSetPrepend : public Kwd
00665 {
00666 public:
00667   void action (const CmtSystem::cmt_string_vector& words,
00668                Use* use,
00669                const cmt_string& file_name,
00670                int line_number)
00671   {
00672     Symbol::action (words, CommandSetPrepend, use);
00673   }
00674 };
00675 
00676 class KwdSetRemove : public Kwd
00677 {
00678 public:
00679   void action (const CmtSystem::cmt_string_vector& words,
00680                Use* use,
00681                const cmt_string& file_name,
00682                int line_number)
00683   {
00684     Symbol::action (words, CommandSetRemove, use);
00685   }
00686 };
00687 
00688 class KwdSetRemoveRegexp : public Kwd
00689 {
00690 public:
00691   void action (const CmtSystem::cmt_string_vector& words,
00692                Use* use,
00693                const cmt_string& file_name,
00694                int line_number)
00695   {
00696     Symbol::action (words, CommandSetRemoveRegexp, use);
00697   }
00698 };
00699 
00700 class KwdSetupScript : public Kwd
00701 {
00702 public:
00703   void action (const CmtSystem::cmt_string_vector& words,
00704                Use* use,
00705                const cmt_string& file_name,
00706                int line_number)
00707   {
00708     Script::action (words, SetupScript, use);
00709     Symbol::action (words, CommandSetupScript, use);
00710   }
00711 };
00712 
00713 class KwdSetupStrategy : public Kwd
00714 {
00715 public:
00716   bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value)
00717   {
00718     bool result = true;
00719 
00720     value = w;
00721 
00722     if (w == "config")
00723       {
00724         strategy = "SetupConfig";
00725       }
00726     else if (w == "no_config")
00727       {
00728         strategy = "SetupConfig";
00729       }
00730     else if (w == "root")
00731       {
00732         strategy = "SetupRoot";
00733       }
00734     else if (w == "no_root")
00735       {
00736         strategy = "SetupRoot";
00737       }
00738     else if (w == "cleanup")
00739       {
00740         strategy = "SetupCleanup";
00741       }
00742     else if (w == "no_cleanup")
00743       {
00744         strategy = "SetupCleanup";
00745       }
00746     else
00747       {
00748         result = false;
00749       }
00750 
00751     return (result);
00752   }
00753 
00754   void action (const CmtSystem::cmt_string_vector& words,
00755                Use* use,
00756                const cmt_string& file_name,
00757                int line_number)
00758   {
00759     cmt_string cmtpath;
00760     cmt_string offset;
00761 
00762     use->get_cmtpath_and_offset (cmtpath, offset);
00763 
00764     Project* p = Project::find_by_cmtpath (cmtpath);
00765 
00766     for (int i = 1; i < words.size (); i++)
00767       {
00768         const cmt_string& w = words[i];
00769 
00770         cmt_string strategy;
00771         cmt_string value;
00772 
00773         bool in_error = false;
00774 
00775         if (decode (w, strategy, value))
00776           {
00777             if (p != 0) p->set_strategy (strategy, value, use->get_package_name ());
00778           }
00779         else
00780           {
00781             in_error = true;
00782 
00783             CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
00784           }
00785       }
00786   }
00787 
00788   void action (const CmtSystem::cmt_string_vector& words,
00789                Project* project,
00790                const cmt_string& file_name,
00791                int line_number)
00792   {
00793     for (int i = 1; i < words.size (); i++)
00794       {
00795         const cmt_string& w = words[i];
00796 
00797         cmt_string strategy;
00798         cmt_string value;
00799 
00800         bool in_error = false;
00801 
00802         if (decode (w, strategy, value))
00803           {
00804             if (project != 0) project->set_strategy (strategy, value, "");
00805           }
00806         else
00807           {
00808             in_error = true;
00809 
00810             CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
00811           }
00812       }
00813   }
00814 };
00815 
00816 class KwdTag : public Kwd
00817 {
00818 public:
00819   void action (const CmtSystem::cmt_string_vector& words,
00820                Use* use,
00821                const cmt_string& file_name,
00822                int line_number)
00823   {
00824     Tag::action (words, use);
00825   }
00826 };
00827 
00828 class KwdTagExclude : public Kwd
00829 {
00830 public:
00831   void action (const CmtSystem::cmt_string_vector& words,
00832                Use* use,
00833                const cmt_string& file_name,
00834                int line_number)
00835   {
00836     Tag::action_exclude (words, use);
00837   }
00838 };
00839 
00840 class KwdUse : public Kwd
00841 {
00842 public:
00843   void action (const CmtSystem::cmt_string_vector& words,
00844                Use* use,
00845                const cmt_string& file_name,
00846                int line_number)
00847   {
00848     Use::action (words, use);
00849   }
00850 
00851   void action (const CmtSystem::cmt_string_vector& words,
00852                Project* project,
00853                const cmt_string& file_name,
00854                int line_number)
00855   {
00856     project->use_action (words[1], words[2]);
00857   }
00858 };
00859 
00860 class KwdVersionStrategy : public Kwd
00861 {
00862 public:
00863   void action (const CmtSystem::cmt_string_vector& words,
00864                Use* use,
00865                const cmt_string& file_name,
00866                int line_number)
00867   {
00868     cerr << "# Package " << use->get_package_name () <<
00869       " sets obsolescent version strategy" << endl;
00870   }
00871 };
00872 
00873 class KwdVersion : public Kwd
00874 {
00875 public:
00876   void action (const CmtSystem::cmt_string_vector& words,
00877                Use* use,
00878                const cmt_string& file_name,
00879                int line_number)
00880   {
00881   }
00882 };
00883 
00884 class KwdDefault : public Kwd
00885 {
00886 public:
00887   void action (const CmtSystem::cmt_string_vector& words,
00888                Use* use,
00889                const cmt_string& file_name,
00890                int line_number)
00891   {
00892     /*
00893       Unknown keyword : just ignore the line
00894     */
00895     if (!Cmt::get_quiet ())
00896       {
00897         cerr << "#CMT> bad syntax in requirements of " << use->get_package_name ()
00898              << " " << use->version << " line #" << line_number;
00899         cerr << " [" << words[0] << "...]" << endl;
00900       }
00901     
00902     CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
00903   }
00904 };
00905 
00906 SyntaxParser& SyntaxParser::instance ()
00907 {
00908   static SyntaxParser p;
00909 
00910   return (p);
00911 }
00912 
00920 void SyntaxParser::parse_requirements (const cmt_string& file_name, Use* use)
00921 {
00922   SyntaxParser& me = instance ();
00923 
00924   if (use != 0)
00925     {
00926       cmt_string buffer;
00927 
00928       use->fill_standard_macros (buffer);
00929 
00930       AccessMode saved_current_access = Cmt::get_current_access ();
00931       Cmt::set_current_access (UserMode);
00932       me.do_parse_text (buffer, "", package_context, use, 0);
00933       Cmt::set_current_access (saved_current_access);
00934     }
00935 
00936   me.do_parse_requirements (file_name, use);
00937 
00938   if (use != 0)
00939     {
00940       use->close_scope_sections ();
00941     }
00942 }
00943 
00946 void SyntaxParser::parse_project_file_text (const cmt_string& text,
00947                                             const cmt_string& file_name,
00948                                             Project* project)
00949 {
00950   SyntaxParser& me = instance ();
00951   me.do_parse_text (text, file_name, project_context, 0, project);
00952 }
00953 
00961 void SyntaxParser::parse_requirements_text (const cmt_string& text,
00962                                             const cmt_string& file_name,
00963                                             Use* use)
00964 {
00965   SyntaxParser& me = instance ();
00966 
00986   AccessMode saved_current_access;
00987 
00988   saved_current_access = Cmt::get_current_access ();
00989 
00990   if (use == 0) use = &(Use::current ());
00991 
00992   if (use != &(Use::current ()))
00993     {
00994       if (Cmt::get_debug ())
00995         {
00996           cout << "parse_requirements_text> set UserMode" << endl;
00997         }
00998 
00999       Cmt::set_current_access (UserMode);
01000     }
01001   else
01002     {
01003       if (Cmt::get_debug ())
01004         {
01005           cout << "parse_requirements_text> set DeveloperMode" << endl;
01006         }
01007 
01008       Cmt::set_current_access (DeveloperMode);
01009     }
01010 
01011   me.do_parse_text (text, file_name, package_context, use, 0);
01012 
01013   Cmt::set_current_access (saved_current_access);
01014 }
01015 
01023 void SyntaxParser::parse_requirements_line (const cmt_string& line,
01024                                             Use* use,
01025                                             const cmt_string& file_name,
01026                                             int line_number)
01027 {
01028   SyntaxParser& me = instance ();
01029   me.do_parse_line (line, file_name, line_number, package_context, use, 0);
01030 }
01031 
01032 SyntaxParser::SyntaxParser ()
01033 {
01034   m_keywords.add ("action", new KwdAction ());
01035   m_keywords.add ("alias", new KwdAlias ());
01036   m_keywords.add ("application", new KwdApplication ());
01037   m_keywords.add ("apply_pattern", new KwdApplyPattern ());
01038   m_keywords.add ("apply_tag", new KwdApplyTag ());
01039   m_keywords.add ("author", new KwdAuthor ());
01040   m_keywords.add ("branches", new KwdBranches ());
01041   m_keywords.add ("build_strategy", new KwdBuildStrategy ());
01042   m_keywords.add ("cleanup_script", new KwdCleanupScript ());
01043   m_keywords.add ("cmtpath_pattern", new KwdCmtPathPattern ());
01044   m_keywords.add ("document", new KwdDocument ());
01045   m_keywords.add ("end_private", new KwdEndPrivate ());
01046   m_keywords.add ("end_public", new KwdEndPublic ());
01047   m_keywords.add ("ignore_pattern", new KwdIgnorePattern ());
01048   m_keywords.add ("include_dirs", new KwdIncludeDirs ());
01049   m_keywords.add ("include_path", new KwdIncludePath ());
01050   m_keywords.add ("language", new KwdLanguage ());
01051   m_keywords.add ("library", new KwdLibrary ());
01052   m_keywords.add ("macro", new KwdMacro ());
01053   m_keywords.add ("macro+", new KwdMacroAppend ());
01054   m_keywords.add ("macro_prepend", new KwdMacroPrepend ());
01055   m_keywords.add ("macro_append", new KwdMacroAppend ());
01056   m_keywords.add ("macro_remove", new KwdMacroRemove ());
01057   m_keywords.add ("macro_remove_regexp", new KwdMacroRemoveRegexp ());
01058   m_keywords.add ("macro_remove_all", new KwdMacroRemoveAll ());
01059   m_keywords.add ("macro_remove_all_regexp", new KwdMacroRemoveAllRegexp ());
01060   m_keywords.add ("make_fragment", new KwdMakeFragment ());
01061   m_keywords.add ("manager", new KwdManager ());
01062   m_keywords.add ("package", new KwdPackage ());
01063   m_keywords.add ("path", new KwdPath ());
01064   m_keywords.add ("path_append", new KwdPathAppend ());
01065   m_keywords.add ("path_prepend", new KwdPathPrepend ());
01066   m_keywords.add ("path_remove", new KwdPathRemove ());
01067   m_keywords.add ("path_remove_regexp", new KwdPathRemoveRegexp ());
01068   m_keywords.add ("pattern", new KwdPattern ());
01069   m_keywords.add ("public", new KwdPublic ());
01070   m_keywords.add ("private", new KwdPrivate ());
01071   m_keywords.add ("project", new KwdProject ());
01072   m_keywords.add ("set", new KwdSet ());
01073   m_keywords.add ("set_append", new KwdSetAppend ());
01074   m_keywords.add ("set_prepend", new KwdSetPrepend ());
01075   m_keywords.add ("set_remove", new KwdSetRemove ());
01076   m_keywords.add ("set_remove_regexp", new KwdSetRemoveRegexp ());
01077   m_keywords.add ("setup_script", new KwdSetupScript ());
01078   m_keywords.add ("setup_strategy", new KwdSetupStrategy ());
01079   m_keywords.add ("tag", new KwdTag ());
01080   m_keywords.add ("tag_exclude", new KwdTagExclude ());
01081   m_keywords.add ("use", new KwdUse ());
01082   m_keywords.add ("version_strategy", new KwdVersionStrategy ());
01083   m_keywords.add ("version", new KwdVersion ());
01084 
01085   m_project_keywords.add ("build_strategy", new KwdBuildStrategy ());
01086   m_project_keywords.add ("container", new KwdContainer ());
01087   m_project_keywords.add ("project", new KwdProject ());
01088   m_project_keywords.add ("setup_strategy", new KwdSetupStrategy ());
01089   m_project_keywords.add ("use", new KwdUse ());
01090 }
01091 
01092 void SyntaxParser::do_parse_requirements (const cmt_string& file_name, Use* use)
01093 {
01094   cmt_string actual_file_name = file_name;
01095   cmt_string text;
01096 
01097   CmtError::clear ();
01098 
01099   if (!CmtSystem::test_file (actual_file_name))
01100     {
01101       actual_file_name = "..";
01102       actual_file_name += CmtSystem::file_separator ();
01103       actual_file_name += "cmt";
01104       actual_file_name += CmtSystem::file_separator ();
01105       actual_file_name += file_name;
01106 
01107       if (!CmtSystem::test_file (actual_file_name))
01108         {
01109           actual_file_name = "..";
01110           actual_file_name += CmtSystem::file_separator ();
01111           actual_file_name += "mgr";
01112           actual_file_name += CmtSystem::file_separator ();
01113           actual_file_name += file_name;
01114 
01115           if (!CmtSystem::test_file (actual_file_name))
01116             {
01117               return;
01118             }
01119         }
01120     }
01121 
01122   text.read (actual_file_name);
01123 
01124   SyntaxParser::parse_requirements_text (text, actual_file_name, use);
01125 }
01126 
01134 void SyntaxParser::do_parse_text (const cmt_string& text,
01135                                   const cmt_string& file_name,
01136                                   ContextType context,
01137                                   Use* use,
01138                                   Project* project)
01139 {
01140   cmt_string line;
01141   int pos;
01142   int max_pos;
01143   int line_number = 1;
01144 
01145   if (context == package_context)
01146     {
01147       if (use == 0) use = &(Use::current ());
01148     }
01149 
01150   m_filtered_text.erase (0);
01151 
01152   pos = 0;
01153   max_pos = text.size ();
01154 
01155   for (pos = 0; pos < max_pos;)
01156     {
01157       int cr = text.find (pos, "\r\n");
01158       int nl = text.find (pos, '\n');
01159       int first = nl;
01160       int length = 1;
01161 
01162       if (cr != cmt_string::npos)
01163         {
01164           if (nl == cmt_string::npos)
01165             {
01166               first = cr;
01167               length = 2;
01168             }
01169           else
01170             {
01171               first = (nl < cr) ? nl : cr;
01172               length = (nl < cr) ? 1 : 2;
01173             }
01174         }
01175 
01176       if (first == cmt_string::npos)
01177         {
01178           text.substr (pos, line);
01179           pos = max_pos;
01180         }
01181       else if (first > pos)
01182         {
01183           text.substr (pos, first - pos, line);
01184           pos = first + length;
01185         }
01186       else
01187         {
01188           line.erase (0);
01189           pos += length;
01190         }
01191 
01192       do_parse_line (line, file_name, line_number, context, use, project);
01193 
01194       if ((Cmt::get_action () == action_check_configuration) && CmtError::has_pending_error ())
01195         {
01196           //break;
01197         }
01198 
01199       line_number++;
01200     }
01201 }
01202 
01203 void SyntaxParser::do_parse_line (const cmt_string& line,
01204                                   const cmt_string& file_name,
01205                                   int line_number,
01206                                   ContextType context,
01207                                   Use* use,
01208                                   Project* project)
01209 {
01210   int length;
01211   int nl;
01212   int back_slash;
01213   cmt_string temp_line = line;
01214 
01215   if (temp_line.size () == 0) return;
01216   if (temp_line[0] == '#') return;
01217 
01218   nl = temp_line.find_last_of ('\n');
01219   if (nl != cmt_string::npos) temp_line.erase (nl);
01220 
01221   length = temp_line.size ();
01222   if (length == 0) return;
01223 
01224   //
01225   // We scan the line for handling backslashes.
01226   //
01227   // o Really terminating backslashes (ie those only followed by spaces/tabs
01228   // mean continued line
01229   //
01230   //
01231 
01232   bool finished = true;
01233 
01234   length = temp_line.size ();
01235 
01236   back_slash = temp_line.find_last_of ('\\');
01237 
01238   if (back_slash != cmt_string::npos)
01239     {
01240       //
01241       // This is the last backslash
01242       // check if there are only space chars after it
01243       //
01244       
01245       bool at_end = true;
01246 
01247       for (int i = (back_slash + 1); i < length; i++)
01248         {
01249           char c = temp_line[i];
01250           if ((c != ' ') && (c != '\t'))
01251             {
01252               at_end = false;
01253               break;
01254             }
01255         }
01256 
01257       if (at_end)
01258         {
01259           temp_line.erase (back_slash);
01260           finished = false;
01261         }
01262       else
01263         {
01264           // This was not a trailing backslash.
01265           finished = true;
01266         }
01267     }
01268 
01269   m_filtered_text += temp_line;
01270 
01271   if (!finished)
01272     {
01273       // We still need to accumulate forthcoming lines
01274       // before parsing the resulting text.
01275       return;
01276     }
01277 
01278   /*
01279     Here a full line (possibly accumulating several lines
01280     ended by backslashes) is parsed :
01281     
01282     o Special characters are filtered now :
01283     
01284     <cmt:tab/>  \t
01285     <cmt:cr/>   \r
01286     <cmt:lf/>   \n
01287     
01288     o Split into words (a word is a string not containing
01289     spaces or enclosed in quotes)
01290 
01291     o Parse the word array (function Select)
01292 
01293   */
01294 
01295   m_filtered_text.replace_all ("<cmt:tab/>", "\t");
01296   m_filtered_text.replace_all ("<cmt:cr/>",  "\r");
01297   m_filtered_text.replace_all ("<cmt:lf/>",  "\n");
01298 
01299   if (Cmt::get_debug ())
01300     {
01301       cout << "parse_requirements_line [" << m_filtered_text << "]" << endl;
01302     }
01303   
01304   static CmtSystem::cmt_string_vector words;
01305   
01306   CmtSystem::split (m_filtered_text, " \t", words);
01307   
01308   if (words.size () != 0)
01309     {
01310       switch (context)
01311         {
01312         case project_context:
01313           do_parse_words (words, file_name, line_number, project);
01314           break;
01315         case package_context:
01316           do_parse_words (words, file_name, line_number, use);
01317           break;
01318         }
01319     }
01320   
01321   m_filtered_text.erase (0);
01322 }
01323 
01324 void SyntaxParser::do_parse_words (const CmtSystem::cmt_string_vector& words,
01325                                    const cmt_string& file_name,
01326                                    int line_number,
01327                                    Use* use)
01328 {
01329   CmtError::clear ();
01330 
01331   if (words.size () == 0) return;
01332 
01333   const cmt_string& command = words[0];
01334 
01335   if (command.size () == 0) return;
01336 
01337   //
01338   // First analyze the syntax
01339   //
01340 
01341   Kwd* keyword = m_keywords.find (command);
01342   if (keyword == 0)
01343     {
01344       /*
01345 
01346         When the first word of the line is not a keyword, it may be an
01347         implicit pattern application.
01348 
01349        */
01350 
01351       Pattern* p = Pattern::find (command);
01352       if (p == 0)
01353         {
01354           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
01355         }
01356       else
01357         {
01358           keyword = m_keywords.find ("apply_pattern");
01359         }
01360     }
01361 
01362   if (CmtError::has_pending_error ())
01363     {
01364       if (!Cmt::get_quiet ())
01365         {
01366           cerr << "#CMT> bad syntax in requirements of " << use->get_package_name ()
01367                << " " << use->version 
01368                << " " << use->specified_path 
01369                << " line #" << line_number;
01370           cerr << " [" << command << " ...]" << endl;
01371         }
01372 
01373       return;
01374     }
01375 
01376   //
01377   // Then interpret the action
01378   //
01379 
01380   keyword->action (words, use, file_name, line_number);
01381 }
01382 
01383 void SyntaxParser::do_parse_words (const CmtSystem::cmt_string_vector& words,
01384                                    const cmt_string& file_name,
01385                                    int line_number,
01386                                    Project* project)
01387 {
01388   CmtError::clear ();
01389 
01390   if (words.size () == 0) return;
01391 
01392   const cmt_string& command = words[0];
01393 
01394   if (command.size () == 0) return;
01395 
01396   //
01397   // First analyze the syntax
01398   //
01399 
01400   Kwd* keyword = m_project_keywords.find (command);
01401   if (keyword == 0)
01402     {
01403       CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
01404     }
01405 
01406   if (CmtError::has_pending_error ())
01407     {
01408       if (!Cmt::get_quiet ())
01409         {
01410           cerr << "#CMT> bad syntax in project file of " << project->get_name ()
01411                << " line #" << line_number;
01412           cerr << " [" << command << " ...]" << endl;
01413         }
01414 
01415       return;
01416     }
01417 
01418   //
01419   // Then interpret the action
01420   //
01421 
01422   keyword->action (words, project, file_name, line_number);
01423 }
01424 
01425 
01426 
01427 

Generated on Mon May 2 10:25:06 2005 for CMT by doxygen 1.3.5