00001
00002
00003
00004
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& ,
00233 int )
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
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
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
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
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
01226
01227
01228
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
01242
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
01265 finished = true;
01266 }
01267 }
01268
01269 m_filtered_text += temp_line;
01270
01271 if (!finished)
01272 {
01273
01274
01275 return;
01276 }
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
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
01339
01340
01341 Kwd* keyword = m_keywords.find (command);
01342 if (keyword == 0)
01343 {
01344
01345
01346
01347
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
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
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
01420
01421
01422 keyword->action (words, project, file_name, line_number);
01423 }
01424
01425
01426
01427