00001
00002
00003
00004
00005
00006
00007 #include <stdlib.h>
00008 #include <stdio.h>
00009
00010 #include "cmt.h"
00011 #include "cmt_cvs.h"
00012 #include "cmt_awk.h"
00013 #include "cmt_symbol.h"
00014 #include "cmt_project.h"
00015
00033 class Grep : public Awk
00034 {
00035 public:
00036
00037 void begin ();
00038 void filter (const cmt_string& line);
00039 const cmt_string& result () const;
00040
00041 private:
00042 cmt_string m_result;
00043 };
00044
00057 class Cut : public Awk
00058 {
00059 public:
00060 Cut (int field);
00061 void begin ();
00062 void filter (const cmt_string& line);
00063 const cmt_string& result () const;
00064
00065 private:
00066 cmt_string m_result;
00067 int m_field;
00068 };
00069
00076 class History
00077 {
00078 public:
00079 static History& instance ();
00080 void clear ();
00081 void install (const cmt_string& line);
00082 bool is_installed (const cmt_string& line);
00083
00084 private:
00085 History ();
00086
00087 cmt_string m_installed;
00088 };
00089
00096 class RecursivePass1 : public Awk
00097 {
00098 public:
00099
00100 void begin ();
00101 void filter (const cmt_string& line);
00102 const cmt_string& result () const;
00103
00104 private:
00105 cmt_string m_result;
00106 bool m_first;
00107 };
00108
00115 class CvsImplementation;
00116 class RecursivePass2 : public Awk
00117 {
00118 public:
00119 RecursivePass2 (CvsImplementation& cvs);
00120 void begin ();
00121 void filter (const cmt_string& line);
00122
00123 private:
00124 CvsImplementation& m_cvs;
00125 };
00126
00133 class RecursivePass3 : public Awk
00134 {
00135 public:
00136
00137 void begin ();
00138 void filter (const cmt_string& line);
00139 const cmt_string& result () const;
00140
00141 private:
00142 cmt_string m_result;
00143 bool m_first;
00144 };
00145
00152 class CvsImplementation;
00153 class RecursivePass4 : public Awk
00154 {
00155 public:
00156 RecursivePass4 (CvsImplementation& cvs);
00157 void begin ();
00158 void filter (const cmt_string& line);
00159
00160 private:
00161 CvsImplementation& m_cvs;
00162 };
00163
00170 class CvsImplementation
00171 {
00172 public:
00173
00174 CvsImplementation ()
00175 {
00176 clear ();
00177 }
00178
00179 void clear ()
00180 {
00181 m_recursive = false;
00182 m_head = false;
00183 m_verbose = false;
00184 m_simulation = false;
00185
00186 m_home_dir = "";
00187 m_checkout_dir = "";
00188 m_version_dir = "";
00189 m_cvs_offset = "";
00190
00191 m_last_module = "";
00192 m_last_cvs_infos = "";
00193 structure_info = "";
00194 error_info = "";
00195 tags_top_info = "";
00196 tags_info = "";
00197 cvsversions_top_info = "";
00198 cvsversions_info = "";
00199 branches_info = "";
00200 subpackages_info = "";
00201 subprojects_info = "";
00202
00203 m_protocol_level = "";
00204
00205 Symbol* symbol = Symbol::find ("cmt_cvs_protocol_level");
00206 if (symbol != 0)
00207 {
00208 m_protocol_level = symbol->build_macro_value ();
00209 Symbol::expand (m_protocol_level);
00210 }
00211 }
00212
00213 CvsImplementation& operator = (const CvsImplementation& other)
00214 {
00215 m_recursive = other.m_recursive;
00216 m_head = other.m_head;
00217 m_verbose = other.m_verbose;
00218 m_simulation = other.m_simulation;
00219
00220 m_home_dir = other.m_home_dir;
00221 m_checkout_dir = other.m_checkout_dir;
00222 m_version_dir = other.m_version_dir;
00223 m_cvs_offset = other.m_cvs_offset;
00224 m_protocol_level = other.m_protocol_level;
00225 m_last_module = other.m_last_module;
00226 m_last_cvs_infos = other.m_last_cvs_infos;
00227
00228 structure_info = other.structure_info;
00229 error_info = other.error_info;
00230 tags_top_info = other.tags_top_info;
00231 tags_info = other.tags_info;
00232 cvsversions_top_info = other.cvsversions_top_info;
00233 cvsversions_info = other.cvsversions_info;
00234 branches_info = other.branches_info;
00235 subpackages_info = other.subpackages_info;
00236 subprojects_info = other.subprojects_info;
00237
00238 return (*this);
00239 }
00240
00244 void filter_list (cmt_string& text, const cmt_regexp& exp)
00245 {
00246 CmtSystem::cmt_string_vector list;
00247
00248 CmtSystem::split (text, " ", list);
00249
00250 int i;
00251
00252 text = "";
00253
00254 for (i = 0; i < list.size (); i++)
00255 {
00256 const cmt_string& s = list[i];
00257 if (exp.match (s))
00258 {
00259 if (i > 0) text += " ";
00260 text += s;
00261 }
00262 }
00263 }
00264
00265 int execute (const cmt_string& command)
00266 {
00267 int status = 0;
00268
00269 if (m_verbose || m_simulation)
00270 {
00271 cout << "#CMT> Executing [" << command << "]" << endl;
00272 }
00273
00274 if (!m_simulation)
00275 {
00276 status = CmtSystem::execute (command);
00277 }
00278
00279 return (status);
00280 }
00281
00282 void execute_and_retry (const cmt_string& command, const cmt_string& message)
00283 {
00284 int status;
00285 int retry = 0;
00286
00287 for (;;)
00288 {
00289 status = execute (command);
00290
00291 if (status != 0)
00292 {
00293 retry++;
00294
00295 cout << "# " << message << ": status=" << status << endl;
00296 cout << "#---------------------------------------------------------" << endl;
00297
00298 if (retry > 5) exit(0);
00299 }
00300 else
00301 {
00302 break;
00303 }
00304 }
00305 }
00306
00307 int execute (const cmt_string& command, cmt_string& out)
00308 {
00309 int status = 0;
00310
00311 if (m_verbose || m_simulation)
00312 {
00313 cout << "#CMT> Executing [" << command << "]" << endl;
00314 }
00315
00316 if (!m_simulation)
00317 {
00318 status = CmtSystem::execute (command, out);
00319 }
00320
00321 return (status);
00322 }
00323
00324
00345 bool check_protocol ()
00346 {
00347 static bool done = false;
00348 static bool found = true;
00349
00350 if (done) return (found);
00351 done = true;
00352
00353 cmt_string cvsroot;
00354
00355 CmtSystem::get_cvsroot (cvsroot);
00356
00357 cmt_string command;
00358
00359 command = "cvs";
00360 if (cvsroot != "")
00361 {
00362 command += " -d ";
00363 command += cvsroot;
00364 }
00365 command += " -Q co -p CVSROOT/loginfo ";
00366
00367 found = false;
00368
00369 cmt_string pattern = ".cmtcvsinfos/";
00370 pattern += m_protocol_level;
00371
00372 cmt_string loginfo;
00373
00374 if (m_simulation)
00375 {
00376 loginfo = pattern;
00377 }
00378
00379 execute (command, loginfo);
00380
00381 int pos = loginfo.find (pattern);
00382
00383 if (pos != cmt_string::npos)
00384 {
00385 found = true;
00386 }
00387
00388 if (m_verbose)
00389 {
00390 if (found)
00391 {
00392 cout << "#CMT> Protocol level " << m_protocol_level << endl;
00393 }
00394 else
00395 {
00396 cout << "#CMT> The CVS pluggin is not installed or is not at protocol level " << m_protocol_level << endl;
00397 }
00398 }
00399
00400 return (found);
00401 }
00402
00410 void retreive_cvs_infos (const cmt_string& module)
00411 {
00412 static const cmt_string cmtcvsinfos = ".cmtcvsinfos";
00413
00414 cmt_string home_dir = CmtSystem::pwd ();
00415
00416
00417
00418
00419 cmt_string tmp_dir = CmtSystem::getenv ("TMPDIR");
00420 if (tmp_dir == "")
00421 {
00422 tmp_dir = CmtSystem::file_separator ();
00423 tmp_dir += "tmp";
00424 }
00425
00426 if (!CmtSystem::cd (tmp_dir))
00427 {
00428 tmp_dir = home_dir;
00429 }
00430
00431 tmp_dir += CmtSystem::file_separator ();
00432 tmp_dir += "cmtcvs";
00433 {
00434 cmt_string temp = CmtSystem::get_temporary_name ();
00435 CmtSystem::basename (temp, temp);
00436
00437 temp.replace_all (".", "");
00438 tmp_dir += temp;
00439 }
00440
00441 if (!CmtSystem::test_directory (tmp_dir))
00442 {
00443 if (!CmtSystem::mkdir (tmp_dir))
00444 {
00445 cout << "#CMT> Cannot create the temporary directory [" << tmp_dir << "]" << endl;
00446 return;
00447 }
00448 }
00449
00450
00451
00452 if (!CmtSystem::cd (tmp_dir))
00453 {
00454 cout << "#CMT> Cannot move to the temporary directory " << tmp_dir << endl;
00455
00456 if (m_verbose)
00457 {
00458 cout << "#CMT> now removing tmp_dir " << tmp_dir << " home=" << home_dir << endl;
00459 }
00460
00461 CmtSystem::remove_directory (tmp_dir);
00462
00463 return;
00464 }
00465
00466 if (m_verbose)
00467 {
00468 cout << "#CMT> cvs infos are now obtained from the temporary directory " << CmtSystem::pwd () << endl;
00469 }
00470
00486 if (!CmtSystem::test_directory (cmtcvsinfos))
00487 {
00488 CmtSystem::mkdir (cmtcvsinfos);
00489 }
00490
00491 CmtSystem::cd (cmtcvsinfos);
00492
00493 cmt_string cvsroot;
00494
00495 CmtSystem::get_cvsroot (cvsroot);
00496
00497 cmt_string command;
00498
00499 command = "cvs";
00500 if (cvsroot != "")
00501 {
00502 command += " -d ";
00503 command += cvsroot;
00504 }
00505 command += " -Q import -m cmt ";
00506
00507 command += cmtcvsinfos;
00508
00509 if (m_protocol_level != "")
00510 {
00511 command += "/";
00512 command += m_protocol_level;
00513 }
00514 command += "/";
00515 command += module;
00516 command += " CMT v1";
00517
00518 m_last_cvs_infos = "";
00519
00520 execute (command, m_last_cvs_infos);
00521
00522 if (m_verbose)
00523 {
00524 cout << "#CMT> now removing tmp_dir " << tmp_dir << " home=" << home_dir << endl;
00525 }
00526
00527 CmtSystem::cd (home_dir);
00528 CmtSystem::remove_directory (tmp_dir);
00529 }
00530
00554 void get_cvs_infos_with_offset (const cmt_string& module)
00555 {
00556 if (!check_protocol ())
00557 {
00558 cout << "#CMT> The CVS pluggin is not installed or is not at protocol level " << m_protocol_level << endl;
00559 return;
00560 }
00561
00562 if (module == "")
00563 {
00564 cout << "#CMT> cmt cvs needs a module name" << endl;
00565 return;
00566 }
00567
00568 if (module == m_last_module)
00569 {
00570 if (m_verbose)
00571 {
00572 cout << "#CMT> cvs infos for module " << module << " already there" << endl;
00573 }
00574 }
00575 else
00576 {
00577 m_last_module = module;
00578
00579 retreive_cvs_infos (module);
00580 }
00581
00586 Grep grep;
00587
00588 grep.run (m_last_cvs_infos, "structure=");
00589
00590 if (grep.result () != "")
00591 {
00592 structure_info = grep.result ();
00593 structure_info.replace ("structure=", "");
00594 }
00595 else
00596 {
00597
00598 structure_info = "package";
00599 }
00600
00601 grep.run (m_last_cvs_infos, "error=");
00602
00603 if (grep.result () != "")
00604 {
00605 error_info = grep.result ();
00606 error_info.replace ("error=", "");
00607 }
00608 else
00609 {
00610 error_info = "";
00611 }
00612
00613 grep.run (m_last_cvs_infos, "tags_top=");
00614
00615 if (grep.result () != "")
00616 {
00617 tags_top_info = grep.result ();
00618 tags_top_info.replace ("tags_top=", "");
00619 }
00620 else
00621 {
00622 tags_top_info = "";
00623 }
00624
00625 grep.run (m_last_cvs_infos, "tags=");
00626
00627 if (grep.result () != "")
00628 {
00629 tags_info = grep.result ();
00630 tags_info.replace ("tags=", "");
00631 }
00632 else
00633 {
00634 tags_info = "";
00635 }
00636
00637 grep.run (m_last_cvs_infos, "cvsversions_top=");
00638
00639 if (grep.result () != "")
00640 {
00641 cvsversions_top_info = grep.result ();
00642 cvsversions_top_info.replace ("cvsversions_top=", "");
00643 }
00644 else
00645 {
00646 cvsversions_top_info = "";
00647 }
00648
00649 grep.run (m_last_cvs_infos, "cvsversions=");
00650
00651 if (grep.result () != "")
00652 {
00653 cvsversions_info = grep.result ();
00654 cvsversions_info.replace ("cvsversions=", "");
00655 }
00656 else
00657 {
00658 cvsversions_info = "";
00659 }
00660
00661 grep.run (m_last_cvs_infos, "branches=");
00662
00663 if (grep.result () != "")
00664 {
00665 branches_info = grep.result ();
00666 branches_info.replace ("branches=", "");
00667 }
00668 else
00669 {
00670 branches_info = "";
00671 }
00672
00673 grep.run (m_last_cvs_infos, "subpackages=");
00674
00675 if (grep.result () != "")
00676 {
00677 subpackages_info = grep.result ();
00678 subpackages_info.replace ("subpackages=", "");
00679 }
00680 else
00681 {
00682 subpackages_info = "";
00683 }
00684
00685 grep.run (m_last_cvs_infos, "subprojects=");
00686
00687 if (grep.result () != "")
00688 {
00689 subprojects_info = grep.result ();
00690 subprojects_info.replace ("subprojects=", "");
00691 }
00692 else
00693 {
00694 subprojects_info = "";
00695 }
00696
00702 cmt_string tag_filter = CmtSystem::getenv ("CMTCVSTAGFILTER");
00703
00704 if (tag_filter != "")
00705 {
00706 cmt_string package;
00707 CmtSystem::basename (module, package);
00708
00709 cmt_string pattern = "<package>";
00710
00711 tag_filter.replace_all (pattern, package);
00712
00713 cmt_regexp exp (tag_filter);
00714
00715 cmt_string text;
00716
00717 filter_list (tags_top_info, exp);
00718 filter_list (tags_info, exp);
00719 filter_list (cvsversions_top_info, exp);
00720 filter_list (cvsversions_info, exp);
00721 }
00722 }
00723
00724 void get_cvs_infos (const cmt_string& cvs_offset, const cmt_string& module)
00725 {
00726 cmt_string full_name;
00727
00728 if (cvs_offset != "")
00729 {
00730 full_name = cvs_offset;
00731 full_name += "/";
00732 while (full_name.find ("//") != cmt_string::npos)
00733 {
00734 full_name.replace_all ("//", "/");
00735 }
00736 }
00737
00738 full_name += module;
00739
00740 get_cvs_infos_with_offset (full_name);
00741 }
00742
00751 bool match_version_request (const cmt_string& text,
00752 const cmt_regexp& version_exp,
00753 cmt_string& version)
00754 {
00755 CmtSystem::cmt_string_vector vs;
00756
00757 CmtSystem::split (text, " \t", vs);
00758
00759 version = "";
00760
00761 for (int i = 0; i < vs.size (); i++)
00762 {
00763 const cmt_string& vv = vs[i];
00764
00765 if (version_exp.match (vv))
00766 {
00767 version = vv;
00768 return (true);
00769 }
00770 }
00771
00772 return (false);
00773 }
00774
00775 bool get_version (const cmt_string& offset,
00776 const cmt_string& product,
00777 const cmt_string& version_request,
00778 cmt_string& module,
00779 cmt_string& version,
00780 bool& at_head)
00781 {
00782 Grep grep;
00783 cmt_string topversions;
00784 cmt_string versions;
00785 cmt_string requested_version = version_request;
00786
00787 at_head = false;
00788
00789 module = "";
00790
00791 if (offset != "")
00792 {
00793 module = offset;
00794 module += "/";
00795 while (module.find ("//") != cmt_string::npos)
00796 {
00797 module.replace_all ("//", "/");
00798 }
00799 }
00800
00801 module += product;
00802
00817 if (m_verbose)
00818 {
00819 cout << "#CMT> requesting cvs infos onto module " << module << endl;
00820 }
00821
00822 get_cvs_infos_with_offset (module);
00823
00824 if (error_info != "")
00825 {
00826 versions = "";
00827 cout << "#CMT> Product " << product << " not found in ${CVSROOT}" << endl;
00828 return (false);
00829 }
00830
00831 versions = tags_top_info;
00832
00833 cmt_string v = version_request;
00834
00835 if (version_request.find ("*") != cmt_string::npos)
00836 {
00837 v.replace_all ("*", ".*");
00838 }
00839 else
00840 {
00841
00842 v += "$";
00843 }
00844
00845 cmt_regexp version_exp (v);
00846
00847 if (!match_version_request (versions, version_exp, version))
00848 {
00849
00850
00851 versions = tags_info;
00852
00853 if (!match_version_request (versions, version_exp, version))
00854 {
00855 version = requested_version;
00856 int pos = 0;
00857 if ((pos = version.find ("*")) != cmt_string::npos)
00858 {
00859
00860
00861
00862
00863
00864
00865
00866
00867 if (pos > 0)
00868 {
00869 char letter = version[pos-1];
00870
00871 static const cmt_string digits = "0123456789";
00872
00873 if (digits.find (letter) == cmt_string::npos)
00874 {
00875
00876 version.replace ("*", "0");
00877 }
00878 else
00879 {
00880
00881 version.replace ("*", "");
00882 }
00883 }
00884 else
00885 {
00886
00887 version = "v0";
00888 }
00889 }
00890 at_head = true;
00891 }
00892 else
00893 {
00894 at_head = false;
00895 }
00896 }
00897 else
00898 {
00899 at_head = true;
00900 }
00901
00906 return (true);
00907 }
00908
00912 cmt_string build_version_directory (const cmt_string& offset,
00913 const cmt_string& product,
00914 const cmt_string& version)
00915 {
00916 cmt_string dir = m_home_dir;
00917
00918 if (m_checkout_dir != "")
00919 {
00920
00921
00922 dir += CmtSystem::file_separator ();
00923 dir += m_checkout_dir;
00924 }
00925
00926 dir += CmtSystem::file_separator ();
00927 dir += offset;
00928 dir += CmtSystem::file_separator ();
00929 dir += product;
00930
00931 if ((structure_info == "project") || (Cmt::get_current_structuring_style () == with_version_directory))
00932 {
00933 dir += CmtSystem::file_separator ();
00934 dir += version;
00935 }
00936
00937 CmtSystem::reduce_file_separators (dir);
00938
00939 return (dir);
00940 }
00941
00945 bool mkdir (const cmt_string& dir)
00946 {
00947 if (m_simulation)
00948 {
00949 cout << "#CMT> Would create the " << dir << " directory" << endl;
00950 }
00951 else
00952 {
00953 if (!CmtSystem::cd (dir))
00954 {
00955 if (m_verbose)
00956 {
00957 cout << "#CMT> About to mkdir " << dir << endl;
00958 }
00959
00960 CmtSystem::mkdir (dir);
00961 if (!CmtSystem::cd (dir))
00962 {
00963 cout << "# Error creating the directory :" << dir << endl;
00964 cout << "#---------------------------------------------------------" << endl;
00965 return (false);
00966 }
00967 }
00968 }
00969 return (true);
00970 }
00971
00977 void add_cmtpath (const cmt_string& dir)
00978 {
00979 static cmt_string CMTPATH;
00980
00981 cmt_string cmtpath = CmtSystem::getenv ("CMTPATH");
00982
00983 if (cmtpath.find (dir) == cmt_string::npos)
00984 {
00985 CMTPATH = "CMTPATH=";
00986 CMTPATH += dir;
00987 CMTPATH += ":";
00988 CMTPATH += cmtpath;
00989
00990 CmtSystem::putenv (CMTPATH);
00991 }
00992
00993 if (m_verbose)
00994 {
00995 cout << "#CMT> CMTPATH=" << CmtSystem::getenv ("CMTPATH") << endl;
00996 }
00997 }
00998
01004 void make_management_files (const cmt_string& module,
01005 const cmt_string& entries_text)
01006 {
01007 if (!CmtSystem::test_directory ("CVS"))
01008 {
01014 if (!mkdir ("CVS")) return;
01015
01016 CmtSystem::cd ("..");
01017
01018 cmt_string s;
01019
01020
01021
01022 CmtSystem::get_cvsroot (s);
01023 s += "\n";
01024
01025 cmt_string f;
01026
01027 f = "CVS";
01028 f += CmtSystem::file_separator ();
01029 f += "Root";
01030
01031 if (m_simulation)
01032 {
01033 cout << "#CMT> Would fill in the CVS/Root file with " << endl;
01034 cout << s << endl;
01035 }
01036 else
01037 {
01038 if (m_verbose)
01039 {
01040 cout << "#CMT> Fill in the CVS/Root file with " << endl;
01041 cout << s << endl;
01042 }
01043 s.write (f);
01044 }
01045
01046
01047
01048 f = "CVS";
01049 f += CmtSystem::file_separator ();
01050 f += "Repository";
01051
01052 CmtSystem::get_cvsroot (s);
01053 if (s[0] == ':')
01054 {
01055 int pos = s.find (1, ":");
01056 s.erase (0, pos+1);
01057 pos = s.find (0, ":");
01058 s.erase (0, pos+1);
01059 }
01060 s += "/";
01061 s += module;
01062 s += "\n";
01063
01064 if (m_simulation)
01065 {
01066 cout << "#CMT> Would fill in the CVS/Repository file with " << endl;
01067 cout << s << endl;
01068 }
01069 else
01070 {
01071 if (m_verbose)
01072 {
01073 cout << "#CMT> Fill in the CVS/Repository file with " << endl;
01074 cout << s << endl;
01075 }
01076 s.write (f);
01077 }
01078 }
01079
01080 if (m_simulation)
01081 {
01082 cout << "#CMT> Would write the top CVS/Entries file with " << endl;
01083 cout << entries_text << endl;
01084 }
01085 else
01086 {
01087 cmt_string entries_file_name;
01088
01089 entries_file_name = "CVS";
01090 entries_file_name += CmtSystem::file_separator ();
01091 entries_file_name += "Entries";
01092
01093 cmt_string text;
01094
01095 if (!text.read (entries_file_name))
01096 {
01097
01098 }
01099
01100 text += entries_text;
01101
01102
01103 if (m_verbose)
01104 {
01105 cout << "#CMT> Fill in the top CVS/Entries file with " << endl;
01106 cout << text << endl;
01107 }
01108
01109 text.write (entries_file_name);
01110 }
01111
01112 }
01113
01117 bool really_checkout_project_contents (const cmt_string& offset,
01118 const cmt_string& project,
01119 const cmt_string& version,
01120 const cmt_string& tag,
01121 const cmt_string& module,
01122 const cmt_string& basedir,
01123 bool at_head,
01124 const cmt_string& currentdir)
01125 {
01126 cmt_string dir = currentdir;
01127
01128 cout << " # get project files into " << dir << endl;
01129
01130 cmt_string version_dir = version;
01131
01132 if (!mkdir (version_dir)) return (false);
01133
01134 dir += CmtSystem::file_separator ();
01135 dir += version_dir;
01136
01137 cmt_string command = "cvs -Q co -P ";
01138 if (!at_head)
01139 {
01140 command += "-r ";
01141 command += (tag != "") ? tag : version;
01142 }
01143
01144 command += " -d cmt ";
01145
01146 command += " ";
01147 command += module;
01148 command += "/cmt";
01149
01150 execute_and_retry (command, "Error getting project CMT contents");
01151
01152 make_management_files (module, "D/cmt////\n");
01153
01154 return (true);
01155 }
01156
01165 bool really_checkout_package_contents (const cmt_string& offset,
01166 const cmt_string& package,
01167 const cmt_string& version,
01168 const cmt_string& module,
01169 const cmt_string& basedir,
01170 bool at_head,
01171 const cmt_string& currentdir)
01172 {
01173 cmt_string dir = currentdir;
01174
01175 cout << " # get top files " << endl;
01176
01177 cmt_string command = "cvs -Q co -P -l ";
01178 if (!at_head)
01179 {
01180 command += "-r ";
01181 command += version;
01182 }
01183
01184 if (Cmt::get_current_structuring_style () == with_version_directory)
01185 {
01186 command += " -d ";
01187 command += version;
01188 }
01189 else
01190 {
01191 command += " -d ";
01192 command += package;
01193
01194
01195 CmtSystem::cd ("..");
01196 CmtSystem::dirname (dir, dir);
01197 }
01198
01199 command += " ";
01200 command += module;
01201
01202 execute_and_retry (command, "Error getting package CMT contents");
01203
01204 if (Cmt::get_current_structuring_style () == with_version_directory)
01205 {
01206 if (!mkdir (version)) return (false);
01207
01208 dir += CmtSystem::file_separator ();
01209 dir += version;
01210 }
01211 else
01212 {
01213 if (!mkdir (package)) return (false);
01214
01215 dir += CmtSystem::file_separator ();
01216 dir += package;
01217 }
01218
01219 if (m_verbose)
01220 {
01221 cout << "#CMT> Now getting subdirectories pwd=" << CmtSystem::pwd () << " dir=" << dir << endl;
01222 }
01223
01224 cmt_string branches = CmtSystem::getenv ("CMTCVSBRANCHES");
01225
01226 if (branches == "")
01227 {
01228 branches = branches_info;
01229 }
01230
01231 CmtSystem::cmt_string_vector branch_vector;
01232
01233 CmtSystem::split (branches, " \t", branch_vector);
01234
01235 cout << " # get branches " << branches << endl;
01236
01237 cmt_string text = "";
01238
01239 command = "";
01240
01241 int i;
01242
01243 for (i = 0; i < branch_vector.size (); i++)
01244 {
01245 cmt_string& branch = branch_vector[i];
01246
01247 if (i > 0)
01248 {
01249 command += CmtSystem::command_separator ();
01250 }
01251
01252 command += "cvs -Q co ";
01253
01254 if (!at_head)
01255 {
01256 command += "-r ";
01257 command += version;
01258 }
01259
01260 command += " -d ";
01261 command += branch;
01262 command += " ";
01263 command += module;
01264 command += "/";
01265 command += branch;
01266
01267 text += "D/";
01268 text += branch;
01269 text += "
01270 }
01271
01272 execute_and_retry (command, "Error getting package contents");
01273
01274 make_management_files (module, text);
01275
01276 return (true);
01277 }
01278
01282 bool really_checkout (const cmt_string& offset,
01283 const cmt_string& product,
01284 const cmt_string& version,
01285 const cmt_string& tag,
01286 const cmt_string& module,
01287 const cmt_string& basedir,
01288 bool at_head)
01289 {
01290 cmt_string dir = basedir;
01291 cmt_string out;
01292
01293 cout << "# ================= working on " << structure_info << " " << product
01294 << " version " << version;
01295
01296 if (at_head) cout << " (At head) ";
01297
01298 cmt_string full_offset;
01299
01300 full_offset = m_cvs_offset;
01301 full_offset += offset;
01302
01303 cmt_string echo_ppath;
01304
01305 if (offset != "")
01306 {
01307 echo_ppath = " path ";
01308 echo_ppath += offset;
01309 }
01310
01311 cout << echo_ppath << " in " << dir << endl;
01312
01313 if ((structure_info == "project") || (Cmt::get_current_structuring_style () == with_version_directory))
01314 {
01315
01316 CmtSystem::dirname (dir, dir);
01317 }
01318
01319 if (!mkdir (dir)) return (false);
01320
01321 if (structure_info == "package")
01322 {
01323 really_checkout_package_contents (offset,
01324 product,
01325 version,
01326 module,
01327 basedir,
01328 at_head,
01329 dir);
01330 }
01331 else if (structure_info == "project")
01332 {
01333 really_checkout_project_contents (offset,
01334 product,
01335 version,
01336 tag,
01337 module,
01338 basedir,
01339 at_head,
01340 dir);
01341 }
01342
01343 return (true);
01344 }
01345
01346 cmt_string find_matching_version (const cmt_string& expression)
01347 {
01348 cmt_string result;
01349
01350
01351
01352
01353
01354
01355 cmt_string dir;
01356 CmtSystem::dirname (expression, dir);
01357 dir += CmtSystem::file_separator ();
01358
01359 cmt_string version;
01360 CmtSystem::basename (expression, version);
01361
01362 if (version.find ("*") == cmt_string::npos)
01363 {
01364
01365 if (CmtSystem::test_directory (expression))
01366 {
01367 result = version;
01368 }
01369 }
01370 else
01371 {
01372 version.replace ("*", ".*");
01373
01374 cmt_regexp exp (version);
01375
01376 CmtSystem::cmt_string_vector list;
01377
01378 CmtSystem::scan_dir (dir, exp, list);
01379
01380 if (list.size () > 0)
01381 {
01382 result = list[0];
01383
01384 CmtSystem::basename (result, result);
01385 }
01386 }
01387
01388 return (result);
01389 }
01390
01397 bool checkout_from_requirements (const cmt_string& requirements_path)
01398 {
01399 static cmt_regexp expression ("^[ \t]*use[ \t]");
01400
01401 cmt_string text;
01402
01403 text.read (requirements_path);
01404
01405 RecursivePass1 p1;
01406 p1.run (text, expression);
01407
01408 bool result = (p1.result () != "");
01409 RecursivePass2 p2 (*this);
01410 p2.run (p1.result ());
01411
01412 return (result);
01413 }
01414
01419 void checkout_from_project_file (const cmt_string& file_name)
01420 {
01421 static cmt_regexp expression ("^[ \t]*use[ \t]");
01422
01423 cmt_string text;
01424
01425 text.read (file_name);
01426
01427 CvsImplementation& me = *this;
01428 CvsImplementation saved;
01429 saved = me;
01430 cmt_string here = CmtSystem::pwd ();
01431
01432 RecursivePass3 p3;
01433 p3.run (text, expression);
01434
01435 RecursivePass4 p4 (*this);
01436 p4.run (p3.result ());
01437
01438 Grep grep;
01439
01440 grep.run (text, "container");
01441 cmt_string container = grep.result ();
01442
01443 if (container != "")
01444 {
01445 static cmt_regexp container_expression ("^[ \t]*container[ \t]");
01446
01447 add_cmtpath (here);
01448
01449 cout << " # --> now getting project packages from the " << container << " " << here << endl;
01450
01451 CmtSystem::cd (here);
01452
01453 RecursivePass1 p1;
01454 p1.run (text, container_expression);
01455
01456 RecursivePass2 p2 (*this);
01457
01458 m_home_dir = CmtSystem::pwd ();
01459 p2.run (p1.result ());
01460 }
01461
01462 CmtSystem::cd (here);
01463 me = saved;
01464 }
01465
01477 void do_checkout_phase2 (const cmt_string& offset,
01478 const cmt_string& product,
01479 const cmt_string& specified_version,
01480 const cmt_string& tag)
01481 {
01482 if (m_verbose)
01483 {
01484 cout << "#CMT> do_checkout_phase2> offset=" << offset
01485 << " " << structure_info << "=" << product
01486 << " specified_version=" << specified_version
01487 << " tag=" << tag
01488 << " pwd=" << CmtSystem::pwd ()
01489 << endl;
01490 }
01491
01492 cmt_string version = specified_version;
01493 cmt_string empty;
01494 cmt_string full_offset;
01495
01496 full_offset = m_cvs_offset;
01497 full_offset += offset;
01498
01499 cmt_string echo_ppath;
01500
01501 if (offset != "")
01502 {
01503 echo_ppath = " path ";
01504 echo_ppath += offset;
01505 }
01506
01507 if (version == "")
01508 {
01509 cout << "# ================= No version specified for " << structure_info << " " << product << endl;
01510 return;
01511 }
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521 cmt_string dir;
01522
01523 dir = build_version_directory (offset, product, version);
01524
01525 bool recursive = m_recursive;
01526
01527 cmt_string effective_version = find_matching_version (dir);
01528
01529 if (effective_version != "")
01530 {
01531 version = effective_version;
01532
01533 dir = build_version_directory (offset, product, version);
01534
01535 cout << "# ================= " << structure_info << " " << product
01536 << " version " << version << echo_ppath
01537 << " already installed in " << dir << endl;
01538
01539 recursive = false;
01540 }
01541 else
01542 {
01543 bool at_head = false;
01544 cmt_string module;
01545 cmt_string cvs_tag = (tag != "") ? tag : version;
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555 if (cvs_tag.find ("*") != cmt_string::npos)
01556 {
01557 cout << "# ================= " << structure_info << " " << product
01558 << " version " << cvs_tag << echo_ppath
01559 << " has wild cards and will not be considered." << endl;
01560 return;
01561 }
01562
01563 if (!get_version (full_offset, product, cvs_tag,
01564 module, cvs_tag, at_head))
01565 {
01566 return;
01567 }
01568
01569 if (m_head)
01570 {
01571 m_head = false;
01572
01573 at_head = true;
01574 }
01575 else
01576 {
01577 at_head = false;
01578 }
01579
01580
01581
01582
01583
01584
01585 if (tag == "")
01586 {
01587
01588
01589
01590 version = cvs_tag;
01591 dir = build_version_directory (offset, product, version);
01592 }
01593
01594 if (CmtSystem::test_directory (dir))
01595 {
01596 cout << "# ================= " << structure_info << " " << product
01597 << " version " << version << echo_ppath
01598 << " already installed." << endl;
01599
01600 recursive = false;
01601 }
01602 else
01603 {
01604
01605
01606
01607
01608 if (!really_checkout (offset, product, version, cvs_tag, module, dir, at_head))
01609 {
01610 cout << "# bad return from really_checkout_product" << endl;
01611 return;
01612 }
01613 }
01614 }
01615
01616
01617
01618
01619
01620 if (m_simulation)
01621 {
01622 cout << "#CMT> " << structure_info << " directory not really created " << dir << endl;
01623 }
01624 else if (structure_info == "package")
01625 {
01626 if (!CmtSystem::cd (dir))
01627 {
01628 cout << "#CMT> Package directory not created " << dir << endl;
01629 return;
01630 }
01631
01632
01633
01634 cmt_string file_name;
01635
01636 file_name = "cmt";
01637 file_name += CmtSystem::file_separator ();
01638 file_name += "requirements";
01639
01640 if (CmtSystem::test_file (file_name))
01641 {
01642 dir += CmtSystem::file_separator ();
01643 dir += "cmt";
01644 CmtSystem::cd ("cmt");
01645
01646 if (Cmt::get_current_structuring_style () == without_version_directory)
01647 {
01648 cmt_string text = version;
01649 text += "\n";
01650 text.write ("version.cmt");
01651 }
01652 }
01653 else
01654 {
01655 file_name = "mgr";
01656 file_name += CmtSystem::file_separator ();
01657 file_name += "requirements";
01658
01659 if (CmtSystem::test_file (file_name))
01660 {
01661 dir += CmtSystem::file_separator ();
01662 dir += "mgr";
01663 CmtSystem::cd ("mgr");
01664 }
01665 else
01666 {
01667 cout << "# " << product << " not a CMT package" << endl;
01668 return;
01669 }
01670 }
01671
01672 if (recursive)
01673 {
01674 cmt_string here = CmtSystem::pwd ();
01675
01676 bool did_recurse = checkout_from_requirements ("requirements");
01677
01678 CmtSystem::cd (here);
01679
01680 if (did_recurse) execute ("cmt -quiet broadcast cmt -quiet config");
01681 }
01682 }
01683 else if (structure_info == "project")
01684 {
01685
01686 if (m_verbose)
01687 {
01688 cout << "#CMT> dir=" << dir << endl;
01689 }
01690
01691 if (!CmtSystem::cd (dir))
01692 {
01693 cout << "#CMT> Project directory not created " << dir << endl;
01694 return;
01695 }
01696
01697 cmt_string file_name;
01698
01699 file_name = "cmt";
01700 file_name += CmtSystem::file_separator ();
01701 file_name += "project.cmt";
01702
01703 if (!CmtSystem::test_file (file_name))
01704 {
01705 cout << "# " << product << " not a CMT project" << endl;
01706 return;
01707 }
01708
01709 if (recursive)
01710 {
01711 checkout_from_project_file (file_name);
01712 }
01713
01714 cout << "# ================= Project " << product << " completed" << endl;
01715
01716 }
01717 }
01718
01729 void do_checkout_phase1 (const cmt_string& module,
01730 const cmt_string& version_dir,
01731 const cmt_string& version_tag)
01732 {
01733 add_cmtpath (m_home_dir);
01734
01735 History& h = History::instance ();
01736
01737 h.clear ();
01738
01739 if (module == "")
01740 {
01741 if (m_verbose)
01742 {
01743 cout << "#CMT> Missing module name" << endl;
01744 }
01745 return;
01746 }
01747
01748 cmt_string offset;
01749 cmt_string product;
01750 cmt_string version;
01751 cmt_string tag;
01752
01753 if (version_tag == "")
01754 {
01755 Cut cut (0);
01756
01757 cmt_string m;
01758 m = m_cvs_offset;
01759 m += module;
01760
01761 get_cvs_infos_with_offset (m);
01762
01763 if (error_info != "")
01764 {
01765 cout << error_info << endl;
01766 return;
01767 }
01768
01769 if (tags_top_info != "") tag = tags_top_info;
01770 else tag = tags_info;
01771
01772 cut.run (tag);
01773
01774 tag = cut.result ();
01775 }
01776 else
01777 {
01778 tag = version_tag;
01779 }
01780
01781 version = (version_dir == "") ? tag : version_dir;
01782
01783 CmtSystem::dirname (module, offset);
01784 CmtSystem::basename (module, product);
01785
01786 cmt_string top_dir;
01787
01788 top_dir = m_home_dir;
01789 top_dir += CmtSystem::file_separator ();
01790 top_dir += m_checkout_dir;
01791 top_dir += CmtSystem::file_separator ();
01792 top_dir += offset;
01793 top_dir += CmtSystem::file_separator ();
01794 top_dir += product;
01795 top_dir += CmtSystem::file_separator ();
01796 top_dir += version;
01797
01798 CmtSystem::reduce_file_separators (top_dir);
01799
01800 if (m_verbose)
01801 {
01802 cout << "#CMT> about to checkout " << structure_info
01803 << " " << product << " version " << version << " into " << top_dir << endl;
01804 }
01805
01806 static const cmt_string empty;
01807 do_checkout_phase2 (offset, product, version, tag);
01808
01809 if (m_simulation) return;
01810
01811 if (!CmtSystem::cd (top_dir)) return;
01812
01813 if (structure_info == "project")
01814 {
01815 cmt_string file_name;
01816
01817 file_name = "cmt";
01818 file_name += CmtSystem::file_separator ();
01819 file_name += "project.cmt";
01820
01821 if (!CmtSystem::test_file (file_name))
01822 {
01823 cout << "# " << product << " was not properly checked out and is missing its cmt/project.cmt file" << endl;
01824 return;
01825 }
01826 }
01827 else
01828 {
01829 cmt_string file_name;
01830
01831 file_name = "cmt";
01832 file_name += CmtSystem::file_separator ();
01833 file_name += "requirements";
01834
01835 if (CmtSystem::test_file (file_name))
01836 {
01837 top_dir += CmtSystem::file_separator ();
01838 top_dir += "cmt";
01839 CmtSystem::cd ("cmt");
01840 }
01841 else
01842 {
01843 file_name = "mgr";
01844 file_name += CmtSystem::file_separator ();
01845 file_name += "requirements";
01846
01847 if (CmtSystem::test_file (file_name))
01848 {
01849 top_dir += CmtSystem::file_separator ();
01850 top_dir += "mgr";
01851 CmtSystem::cd ("mgr");
01852 }
01853 else
01854 {
01855 cout << "# " << product << " was not properly checked out and is missing its cmt/requirements file" << endl;
01856 return;
01857 }
01858 }
01859
01860 if (m_verbose)
01861 {
01862 cout << "#CMT> product " << product << " has been checked out" << endl;
01863 }
01864
01865 if (!m_recursive)
01866 {
01867 execute ("cmt -quiet config");
01868 }
01869 }
01870 }
01871
01872 void help ()
01873 {
01874 cout << "> cd <some work area>" << endl;
01875 cout << "> cmt checkout [modifier ...] <package|project>" << endl;
01876 cout << "" << endl;
01877 cout << " modifier :" << endl;
01878 cout << " -l Do not process used packages (default)." << endl;
01879 cout << " -R Process used products recursively." << endl;
01880 cout << " -r rev Check out version tag. (is sticky)" << endl;
01881 cout << " -vd dir Use this version directory instead of CVS tag." << endl;
01882 cout << " -d dir Check out into dir instead of module name." << endl;
01883 cout << " -o offset Offset in the CVS repository" << endl;
01884 cout << " -requirements <requirements file path> Check out packages referenced in this requirements file" << endl;
01885 cout << " -n simulation mode on" << endl;
01886 cout << " -v verbose mode on" << endl;
01887 cout << " --help print this help" << endl;
01888 cout << "" << endl;
01889 cout << "> cmt cvstags <package|project>" << endl;
01890 cout << "> cmt cvssubpackages <directory>" << endl;
01891 cout << "> cmt cvssubprojects <directory>" << endl;
01892 cout << "" << endl;
01893 }
01894
01899 void tags (const CmtSystem::cmt_string_vector& arguments)
01900 {
01901 if (arguments.size () < 1)
01902 {
01903 help ();
01904 return;
01905 }
01906
01907 if (CmtSystem::getenv ("CVSROOT") == "")
01908 {
01909 cout << "# Please set CVSROOT first !" << endl;
01910 return;
01911 }
01912
01913 m_cvs_offset = CmtSystem::getenv ("CMTCVSOFFSET");
01914 if (m_cvs_offset != "")
01915 {
01916 m_cvs_offset += "/";
01917 m_cvs_offset.replace_all ("//", "/");
01918 }
01919
01920 bool all = false;
01921
01922 for (int arg = 0; arg < arguments.size (); arg++)
01923 {
01924 const cmt_string& option = arguments[arg];
01925
01926 if (option == "-all")
01927 {
01928 all = true;
01929 }
01930 else
01931 {
01932 get_cvs_infos (CmtSystem::getenv ("CMTCVSOFFSET"), option);
01933
01934 if (error_info != "")
01935 {
01936 cout << error_info << endl;
01937 }
01938 else
01939 {
01940 cmt_string tags;
01941
01942 if (all)
01943 {
01944 tags = cvsversions_top_info;
01945 tags += " ";
01946 tags += cvsversions_info;
01947 }
01948 else
01949 {
01950 tags = tags_top_info;
01951 tags += " ";
01952 tags += tags_info;
01953 }
01954
01955 CmtSystem::cmt_string_vector v;
01956
01957 CmtSystem::split (tags, " \t", v);
01958 for (int i = 0; i < v.size (); i++)
01959 {
01960 const cmt_string& s = v[i];
01961 cout << s << endl;
01962 }
01963 }
01964 }
01965 }
01966 }
01967
01972 void branches (const cmt_string& module)
01973 {
01974 cmt_string out;
01975
01976 get_cvs_infos (CmtSystem::getenv ("CMTCVSOFFSET"), module);
01977
01978 if (error_info != "")
01979 {
01980 cout << error_info << endl;
01981 }
01982 else
01983 {
01984 cout << branches_info << endl;
01985 }
01986 }
01987
01992 void subpackages (const cmt_string& module)
01993 {
01994 cmt_string out;
01995
01996 get_cvs_infos (CmtSystem::getenv ("CMTCVSOFFSET"), (module == "") ? "." : module);
01997
01998 if (error_info != "")
01999 {
02000 cout << error_info << endl;
02001 }
02002 else
02003 {
02004 cout << subpackages_info << endl;
02005 }
02006 }
02007
02012 void subprojects (const cmt_string& module)
02013 {
02014 cmt_string out;
02015
02016 get_cvs_infos (CmtSystem::getenv ("CMTCVSOFFSET"), (module == "") ? "." : module);
02017
02018 if (error_info != "")
02019 {
02020 cout << error_info << endl;
02021 }
02022 else
02023 {
02024 cout << subprojects_info << endl;
02025 }
02026 }
02027
02033 void checkout (const CmtSystem::cmt_string_vector& arguments)
02034 {
02035 if (arguments.size () < 1)
02036 {
02037 help ();
02038 return;
02039 }
02040
02041 if (CmtSystem::getenv ("CVSROOT") == "")
02042 {
02043 cout << "# Please set CVSROOT first !" << endl;
02044 return;
02045 }
02046
02047 m_home_dir = CmtSystem::pwd ();
02048 m_checkout_dir = "";
02049 m_version_dir = "";
02050 m_cvs_offset = "";
02051
02052 cmt_string module;
02053
02054 m_recursive = false;
02055
02056 bool need_version_tag = false;
02057 cmt_string version_tag;
02058
02059 bool need_checkout_dir = false;
02060 bool need_cvs_offset = false;
02061 bool need_requirements_file = false;
02062 bool need_version_dir = false;
02063
02064 m_simulation = false;
02065
02066 m_verbose = false;
02067
02068 m_head = true;
02069
02070 m_cvs_offset = CmtSystem::getenv ("CMTCVSOFFSET");
02071 if (m_cvs_offset != "")
02072 {
02073 m_cvs_offset += "/";
02074 m_cvs_offset.replace_all ("//", "/");
02075 }
02076
02077 for (int arg = 0; arg < arguments.size (); arg++)
02078 {
02079 const cmt_string& option = arguments[arg];
02080
02081 if (need_version_tag)
02082 {
02083 need_version_tag = false;
02084
02085 if (option == "HEAD")
02086 {
02087 m_head = true;
02088 }
02089 else
02090 {
02091 version_tag = option;
02092 }
02093 }
02094 else if (need_checkout_dir)
02095 {
02096 need_checkout_dir = false;
02097 m_checkout_dir = option;
02098 }
02099 else if (need_version_dir)
02100 {
02101 need_version_dir = false;
02102 m_version_dir = option;
02103 }
02104 else if (need_cvs_offset)
02105 {
02106 need_cvs_offset = false;
02107 m_cvs_offset = option;
02108 m_cvs_offset += '/';
02109 m_cvs_offset.replace_all ("//", "/");
02110 }
02111 else if (need_requirements_file)
02112 {
02113 need_requirements_file = false;
02114 m_head = false;
02115 checkout_from_requirements (option);
02116 }
02117 else
02118 {
02119 if (option == "-R")
02120 {
02121 m_recursive = true;
02122 }
02123 else if (option == "-l")
02124 {
02125 m_recursive = false;
02126 }
02127 else if (option == "-r")
02128 {
02129 need_version_tag = true;
02130 m_head = false;
02131 }
02132 else if (option == "-d")
02133 {
02134 need_checkout_dir = true;
02135 }
02136 else if (option == "-o")
02137 {
02138 need_cvs_offset = true;
02139 }
02140 else if (option == "-n")
02141 {
02142 m_simulation = true;
02143 }
02144 else if (option == "-v")
02145 {
02146 m_verbose = true;
02147 }
02148 else if (option == "-vd")
02149 {
02150 need_version_dir = true;
02151 }
02152 else if (option == "-requirements")
02153 {
02154 need_requirements_file = true;
02155 }
02156 else if (option == "--help")
02157 {
02158 help ();
02159 return;
02160 }
02161 else if (option[0] == '-')
02162 {
02163 help ();
02164 return;
02165 }
02166 else
02167 {
02168 do_checkout_phase1 (option, m_version_dir, version_tag);
02169 }
02170 }
02171 }
02172 }
02173
02174 private:
02175
02176 bool m_recursive;
02177 bool m_head;
02178 bool m_verbose;
02179 bool m_simulation;
02180
02181 cmt_string m_home_dir;
02182 cmt_string m_checkout_dir;
02183 cmt_string m_version_dir;
02184 cmt_string m_cvs_offset;
02185
02186 cmt_string m_protocol_level;
02187 cmt_string m_last_module;
02188 cmt_string m_last_cvs_infos;
02189 cmt_string structure_info;
02190 cmt_string error_info;
02191 cmt_string tags_top_info;
02192 cmt_string tags_info;
02193 cmt_string cvsversions_top_info;
02194 cmt_string cvsversions_info;
02195 cmt_string branches_info;
02196 cmt_string subpackages_info;
02197 cmt_string subprojects_info;
02198 };
02199
02200
02201
02202 void Grep::begin ()
02203 {
02204 m_result = "";
02205 }
02206
02207 void Grep::filter (const cmt_string& line)
02208 {
02209
02210
02211 if (m_result != "") m_result += " ";
02212 m_result += line;
02213 }
02214
02215 const cmt_string& Grep::result () const
02216 {
02217 return (m_result);
02218 }
02219
02220
02221
02222 Cut::Cut (int field)
02223 {
02224 m_field = field;
02225 }
02226
02227 void Cut::begin ()
02228 {
02229
02230 m_result = "";
02231 }
02232
02233 void Cut::filter (const cmt_string& line)
02234 {
02235
02236
02237 static CmtSystem::cmt_string_vector words;
02238
02239 CmtSystem::split (line, " \t", words);
02240
02241 if (words.size () <= m_field) return;
02242
02243 if (m_result != "") m_result += " ";
02244 m_result += words[m_field];
02245 }
02246
02247 const cmt_string& Cut::result () const
02248 {
02249 return (m_result);
02250 }
02251
02252
02253
02254
02255 History& History::instance ()
02256 {
02257 static History h;
02258 return (h);
02259 }
02260
02261 void History::clear ()
02262 {
02263 m_installed = "";
02264 }
02265
02266 void History::install (const cmt_string& line)
02267 {
02268 m_installed += "|";
02269 m_installed += line;
02270 m_installed += "|";
02271 }
02272
02273 bool History::is_installed (const cmt_string& line)
02274 {
02275 if (m_installed.find (line) != cmt_string::npos)
02276 {
02277 return (true);
02278 }
02279
02280 return (false);
02281 }
02282
02283 History::History ()
02284 {
02285 }
02286
02287
02288
02289
02290 void RecursivePass1::begin ()
02291 {
02292 m_first = true;
02293 m_result = "";
02294 }
02295
02296 void RecursivePass1::filter (const cmt_string& line)
02297 {
02298
02299
02300
02301 if (line.find ("use CMT") != cmt_string::npos) return;
02302 if (line.find ("use cmt") != cmt_string::npos) return;
02303
02304 History& h = History::instance ();
02305
02306 if (h.is_installed (line)) return;
02307
02308 CmtSystem::cmt_string_vector words;
02309
02310 CmtSystem::split (line, " \t", words);
02311
02312 enum
02313 {
02314 need_package,
02315 need_version,
02316 need_path,
02317 no_need
02318 } state = need_package;
02319
02320 cmt_string package;
02321 cmt_string version;
02322 cmt_string path;
02323
02324 for (int i = 1; i < words.size (); i++)
02325 {
02326 const cmt_string& s = words[i];
02327
02328 if (s[0] == '-') continue;
02329
02330 switch (state)
02331 {
02332 case need_package:
02333 package = s;
02334 state = need_version;
02335 break;
02336 case need_version:
02337 version = s;
02338 state = need_path;
02339 break;
02340 case need_path:
02341 path = s;
02342 state = no_need;
02343 break;
02344 }
02345 }
02346
02347 if (version.find ("*") != cmt_string::npos)
02348 {
02349
02350
02351
02352
02353
02354 return;
02355 }
02356
02362 m_result += line;
02363 m_result += "\n";
02364
02365 if (m_first)
02366 {
02367 m_first = false;
02368 cout << " # --> now propagate cmt checkout to :" << endl;
02369 }
02370
02371 cout << " # " << package << " " << version << " " << path << endl;
02372 }
02373
02374 const cmt_string& RecursivePass1::result () const
02375 {
02376 return (m_result);
02377 }
02378
02379
02380
02381 RecursivePass2::RecursivePass2 (CvsImplementation& cvs) : m_cvs (cvs)
02382 {
02383 }
02384
02385 void RecursivePass2::begin ()
02386 {
02387 }
02388
02389 void RecursivePass2::filter (const cmt_string& line)
02390 {
02391
02392
02393
02400 History& h = History::instance ();
02401
02402 if (h.is_installed (line)) return;
02403
02404 h.install (line);
02405
02406 CmtSystem::cmt_string_vector words;
02407
02408 CmtSystem::split (line, " \t", words);
02409
02410 enum
02411 {
02412 need_package,
02413 need_version,
02414 need_path,
02415 no_need
02416 } state = need_package;
02417
02418 cmt_string package;
02419 cmt_string version;
02420 cmt_string path;
02421
02422 for (int i = 1; i < words.size (); i++)
02423 {
02424 const cmt_string& s = words[i];
02425
02426 if (s[0] == '-') continue;
02427
02428 switch (state)
02429 {
02430 case need_package:
02431 package = s;
02432 state = need_version;
02433 break;
02434 case need_version:
02435 version = s;
02436 state = need_path;
02437 break;
02438 case need_path:
02439 path = s;
02440 state = no_need;
02441 break;
02442 }
02443 }
02444
02445 if (version.find ("*") != cmt_string::npos)
02446 {
02447
02448
02449
02450
02451
02452 }
02453 else
02454 {
02455 static const cmt_string empty;
02456 m_cvs.do_checkout_phase2 (path, package, version, empty);
02457 }
02458 }
02459
02460
02461
02462 void RecursivePass3::begin ()
02463 {
02464 m_first = true;
02465 m_result = "";
02466 }
02467
02468 void RecursivePass3::filter (const cmt_string& line)
02469 {
02470 History& h = History::instance ();
02471
02472 if (h.is_installed (line)) return;
02473
02474 CmtSystem::cmt_string_vector words;
02475
02476 CmtSystem::split (line, " \t", words);
02477
02478 enum
02479 {
02480 need_project,
02481 need_version,
02482 need_tag,
02483 no_need
02484 } state = need_project;
02485
02486 cmt_string project;
02487 cmt_string version;
02488 cmt_string tag;
02489
02490 for (int i = 1; i < words.size (); i++)
02491 {
02492 const cmt_string& s = words[i];
02493
02494 switch (state)
02495 {
02496 case need_project:
02497 project = s;
02498 state = need_version;
02499 break;
02500 case need_version:
02501 version = s;
02502 state = need_tag;
02503 break;
02504 case need_tag:
02505 tag = s;
02506 state = no_need;
02507 break;
02508 }
02509 }
02510
02511 if (version.find ("*") != cmt_string::npos)
02512 {
02513
02514
02515
02516
02517
02518 return;
02519 }
02520
02526 m_result += line;
02527 m_result += "\n";
02528
02529 if (m_first)
02530 {
02531 m_first = false;
02532 cout << " # --> now propagate cmt checkout to :" << endl;
02533 }
02534
02535 cout << " # " << project << " " << version << " " << tag << endl;
02536 }
02537
02538 const cmt_string& RecursivePass3::result () const
02539 {
02540 return (m_result);
02541 }
02542
02543
02544
02545 RecursivePass4::RecursivePass4 (CvsImplementation& cvs) : m_cvs (cvs)
02546 {
02547 }
02548
02549 void RecursivePass4::begin ()
02550 {
02551 }
02552
02553 void RecursivePass4::filter (const cmt_string& line)
02554 {
02555
02556
02557
02564 History& h = History::instance ();
02565
02566 if (h.is_installed (line)) return;
02567
02568 h.install (line);
02569
02570 CmtSystem::cmt_string_vector words;
02571
02572 CmtSystem::split (line, " \t", words);
02573
02574 enum
02575 {
02576 need_project,
02577 need_version,
02578 need_tag,
02579 no_need
02580 } state = need_project;
02581
02582 cmt_string project;
02583 cmt_string version;
02584 cmt_string tag;
02585
02586 for (int i = 1; i < words.size (); i++)
02587 {
02588 const cmt_string& s = words[i];
02589
02590 switch (state)
02591 {
02592 case need_project:
02593 project = s;
02594 state = need_version;
02595 break;
02596 case need_version:
02597 version = s;
02598 state = need_tag;
02599 break;
02600 case need_tag:
02601 tag = s;
02602 state = no_need;
02603 break;
02604 }
02605 }
02606
02607 if (version.find ("*") != cmt_string::npos)
02608 {
02609
02610
02611
02612
02613
02614 }
02615 else
02616 {
02617 static const cmt_string empty;
02618 m_cvs.do_checkout_phase2 (empty, project, version, tag);
02619 }
02620 }
02621
02622
02623
02624 void Cvs::tags (const CmtSystem::cmt_string_vector& arguments)
02625 {
02626 CvsImplementation cvs;
02627
02628 cvs.tags (arguments);
02629 }
02630
02631 void Cvs::branches (const cmt_string& module)
02632 {
02633 CvsImplementation cvs;
02634
02635 cvs.branches (module);
02636 }
02637
02638 void Cvs::subpackages (const cmt_string& module)
02639 {
02640 CvsImplementation cvs;
02641
02642 cvs.subpackages (module);
02643 }
02644
02645 void Cvs::subprojects (const cmt_string& module)
02646 {
02647 CvsImplementation cvs;
02648
02649 cvs.subprojects (module);
02650 }
02651
02652 void Cvs::checkout (const CmtSystem::cmt_string_vector& arguments)
02653 {
02654 CvsImplementation cvs;
02655
02656 cvs.checkout (arguments);
02657 }
02658