#include #include #include /* #--------------------------------------------------------------------- # # This program should be installed within the loginfo file of CVS # using the following line : # # ... #.cmtcvsinfos (${CMTROOT}\cmtcvs\v1\VisualC\cmtcvs.exe %s) # ... # # and is used whenever one tries to import a module named .cmtcvsinfos/ # #--------------------------------------------------------------------- */ // // This global flag is set when the string "/cmtcvstest/" is found in // the module argument. This can be used to change the default // behaviour of this pluggin. // // Eg. It can be used to experiment new features. // static bool cmtcvstest = false; //--------------------------------------------------------------------- static cmt_string get_cvsroot (cmt_string& result) { //echo ${CVSROOT} | sed -e 's#^:[^:]*:##' CmtSystem::get_cvsroot (result); int pos = result.find (":"); if (pos == 0) { pos = result.find (1, ":"); result.erase (0, pos+1); } return (result); } static void clear_cmtcvsinfos () { cmt_string dir; get_cvsroot (dir); dir += CmtSystem::file_separator (); dir += ".cmtcvsinfos"; CmtSystem::cmt_string_vector files; CmtSystem::scan_dir (dir, files); for (int i = 0; i < files.size (); i++) { const cmt_string& f = files[i]; CmtSystem::remove_directory (f); } } //--------------------------------------------------------------------- static bool check_head (const cmt_string& head, const cmt_string& version) { CmtSystem::cmt_string_vector hlist; CmtSystem::cmt_string_vector vlist; CmtSystem::split (head, " ", hlist); CmtSystem::split (version, " ", vlist); int nh = hlist.size (); //int nv = vlist.size (); for (int i = 0; i < nh; ++i) { const cmt_string& h = hlist[i]; const cmt_string& v = vlist[i]; if (h != v) return (false); } return (true); } //--------------------------------------------------------------------- // Question: is v1 newer than v2? // static bool check_newer (const cmt_string& v1, const cmt_string& v2) { if (v2 == "") return (true); if (v1 == "") return (false); CmtSystem::cmt_string_vector list1; CmtSystem::cmt_string_vector list2; CmtSystem::split (v1, ".", list1); CmtSystem::split (v2, ".", list2); int n1 = list1.size (); int n2 = list2.size (); //cerr << "checknewer v1=" << v1 << " v2=" << v2 << " n1=" << n1 << " n2=" << n2 << endl; /* v1 = a1.a2.a3.a4 v2 = b1.b2.b3 {i = 0.. min(n1,n2) | if (ai > bi) -> [v1 newer than v2] } [1.2.5 vs 1.2.4] then if (n1 < n2} [v2 newer] [1.2 vs 1.2.5] if (n1 > n2) [v1 newer] [1.2.5 vs 1.2] */ for (int i = 0; i < n1; ++i) { if (i >= n2) { // cerr << "n1 > n2" << endl; return (false); } const cmt_string& s1 = list1[i]; const cmt_string& s2 = list2[i]; int i1; int i2; i1 = atoi (s1.c_str ()); i2 = atoi (s2.c_str ()); //cerr << " i1=" << i1 << " i2=" << i2 << endl; if (i1 > i2) return (true); // v1 newer if (i1 < i2) return (false); // v2 newer } // n2 > n1 // v2 newer //cerr << "n2 > n1" << endl; return (false); } typedef enum { no_structure, in_project, in_package } StructureType; //--------------------------------------------------------------------- static StructureType get_tags (const cmt_string& module, CmtSystem::cmt_string_vector& toptags, CmtSystem::cmt_string_vector& tags, CmtSystem::cmt_string_vector& topcvsversions, CmtSystem::cmt_string_vector& cvsversions) { cmt_string package; cmt_string container; CmtSystem::basename (module, package); CmtSystem::dirname (module, container); CmtSystem::dirname (container, container); //cout << "package=" << package << endl; //cout << "container=" << container << endl; /* # First figure out which test file will be used to retreive the tags # o requirements file is considered first # o then any other file in the top directory # */ StructureType result = in_project; cmt_string test_file; bool found = false; get_cvsroot (test_file); test_file += CmtSystem::file_separator (); test_file += module; test_file += CmtSystem::file_separator (); test_file += "cmt"; test_file += CmtSystem::file_separator (); test_file += "project.cmt,v"; found = CmtSystem::test_file (test_file); if (!found) { // not a CMT project // try it as a CMT package with cmt directory result = in_package; get_cvsroot (test_file); test_file += CmtSystem::file_separator (); test_file += module; test_file += CmtSystem::file_separator (); test_file += "cmt"; test_file += CmtSystem::file_separator (); test_file += "requirements,v"; found = CmtSystem::test_file (test_file); } if (!found) { // try it as a CMT package with mgr directory get_cvsroot (test_file); test_file += CmtSystem::file_separator (); test_file += module; test_file += CmtSystem::file_separator (); test_file += "mgr"; test_file += CmtSystem::file_separator (); test_file += "requirements,v"; found = CmtSystem::test_file (test_file); } if (!found) { // try it as a CMT package with cmt directory but in Attic get_cvsroot (test_file); test_file += CmtSystem::file_separator (); test_file += module; test_file += CmtSystem::file_separator (); test_file += "cmt"; test_file += CmtSystem::file_separator (); test_file += "Attic"; test_file += CmtSystem::file_separator (); test_file += "requirements,v"; found = CmtSystem::test_file (test_file); } if (!found) { // try it as an old SRT package (should be obsolete) get_cvsroot (test_file); test_file += CmtSystem::file_separator (); test_file += module; test_file += CmtSystem::file_separator (); test_file += "PACKAGE,v"; found = CmtSystem::test_file (test_file); } if (!found) { // Structure not recognized (should we take the first file?) result = no_structure; return (result); } /* #symbols # v10:1.1.1.1 # v2:1.1.1.1 # v1r2:1.1.1.1 # v1r1:1.1.1.1 # v1:1.1.1.1 # cmt:1.1.1; #locks; strict; # # Then extract all tags from the file header # one line per tag : # # : # */ cmt_string top; cmt_string temp; temp.read (test_file); int pos = temp.find ("symbols"); temp.erase (0, pos + 7); pos = temp.find ("locks"); temp.erase (pos); //cerr << "temp=[" << temp << "]" << endl; CmtSystem::cmt_string_vector words; CmtSystem::split (temp, " \t\n", words); int i; CmtSystem::cmt_string_vector alltags; for (i = 0; i < words.size (); i++) { const cmt_string& s = words[i]; CmtSystem::cmt_string_vector w; CmtSystem::split (s, ".", w); int n = w.size (); //cerr << "level=" << n << endl; if ((n == 2) || (n == 4) || (n == 6)) { cmt_string& t = alltags.add (); t = s; } } /*# # Compute the most recent tag (using the cvs version ids) #*/ for (i = 0; i < alltags.size (); ++i) { const cmt_string& s = alltags[i]; cmt_string tag = s; pos = tag.find (":"); tag.erase (pos); cmt_string v = s; v.replace (";", ""); v.erase (0, pos+1); //cerr << "s=" << s << " v=" << v << " top=" << top << endl; if (check_newer (v, top)) { //cerr << v << " plus recent que " << top << endl; top = v; } } // cerr << "topv=" << top << endl; bool has_container = false; bool has_package = false; // // Atlas specific behaviour which consists in detecting tags // with a pattern -xxx // for (i = 0; i < alltags.size (); ++i) { const cmt_string& s = alltags[i]; // Get the symbolic tag cmt_string tag = s; pos = tag.find (":"); if (pos == cmt_string::npos) continue; tag.erase (pos); // Analyze its structure cmt_string name = tag; pos = name.find ("-"); if (pos != cmt_string::npos) { name.erase (pos); } if (name == container) { has_container = true; } else if (name == package) { has_package = true; } } /*# # Split the tag list into tags that have same cvs-version-id than # the top tag (tags_tops) and older ones (tags). #*/ toptags.clear (); tags.clear (); topcvsversions.clear (); cvsversions.clear (); for (i = 0; i < alltags.size (); ++i) { static const cmt_string digits = "0123456789"; const cmt_string& s = alltags[i]; cmt_string tag = s; pos = tag.find (":"); tag.erase (pos); cmt_string v = s; v.replace (";", ""); v.erase (0, pos+1); cmt_string fullv = s; fullv.replace (";", ""); cmt_string digit; cmt_string name = tag; pos = name.find ("-"); if (pos != cmt_string::npos) { digit = name[pos+1]; name.erase (pos); } //cout << "tag=" << tag << " name=" << name << " v=" << v << " package=" << package << endl; if (!has_package || ((name == package) && (digits.find (digit) != cmt_string::npos ))) { if (v == top) { toptags.push_back (tag); topcvsversions.push_back (fullv); } else { tags.push_back (tag); cvsversions.push_back (fullv); } } } return (result); } //--------------------------------------------------------------------- static cmt_string get_branches (const cmt_string& module) { cmt_string result; cmt_string dir; get_cvsroot (dir); dir += CmtSystem::file_separator (); dir += module; CmtSystem::cmt_string_vector files; CmtSystem::scan_dir (dir, files); for (int i = 0; i < files.size (); i++) { const cmt_string& branch = files[i]; if (!CmtSystem::test_directory (branch)) continue; cmt_string t; CmtSystem::basename (branch, t); if (t == "Attic") continue; if (t == "CVSROOT") continue; if (t == "defunct.CVS") continue; if (t == ".cmtcvsinfos") continue; if (t == ".cmtcvsinfostest") continue; if (t == ".cmtcvstest") continue; t = branch; t += CmtSystem::file_separator (); t += "cmt"; t += CmtSystem::file_separator (); t += "requirements,v"; if (CmtSystem::test_file (t)) continue; t = branch; t += CmtSystem::file_separator (); t += "mgr"; t += CmtSystem::file_separator (); t += "requirements,v"; if (CmtSystem::test_file (t)) continue; t = branch; t += CmtSystem::file_separator (); t += "cmt"; t += CmtSystem::file_separator (); t += "project.cmt,v"; if (CmtSystem::test_file (t)) continue; CmtSystem::basename (branch, t); if (result != "") result += " "; result += t; } return (result); } //--------------------------------------------------------------------- static cmt_string get_subpackages (const cmt_string& module) { cmt_string result; cmt_string dir; get_cvsroot (dir); dir += CmtSystem::file_separator (); dir += module; CmtSystem::cmt_string_vector files; CmtSystem::scan_dir (dir, files); for (int i = 0; i < files.size (); i++) { const cmt_string& subpackage = files[i]; if (!CmtSystem::test_directory (subpackage)) continue; cmt_string t; CmtSystem::basename (subpackage, t); if (t == "Attic") continue; t = subpackage; t += CmtSystem::file_separator (); t += "cmt"; t += CmtSystem::file_separator (); t += "requirements,v"; if (CmtSystem::test_file (t)) { CmtSystem::basename (subpackage, t); if (result != "") result += " "; result += t; } else { t = subpackage; t += CmtSystem::file_separator (); t += "mgr"; t += CmtSystem::file_separator (); t += "requirements,v"; if (CmtSystem::test_file (t)) { CmtSystem::basename (subpackage, t); if (result != "") result += " "; result += t; } } } return (result); } //--------------------------------------------------------------------- static cmt_string get_subprojects (const cmt_string& module) { cmt_string result; cmt_string dir; get_cvsroot (dir); dir += CmtSystem::file_separator (); dir += module; CmtSystem::cmt_string_vector files; CmtSystem::scan_dir (dir, files); for (int i = 0; i < files.size (); i++) { const cmt_string& subproject = files[i]; if (!CmtSystem::test_directory (subproject)) continue; cmt_string t; CmtSystem::basename (subproject, t); if (t == "Attic") continue; t = subproject; t += CmtSystem::file_separator (); t += "cmt"; t += CmtSystem::file_separator (); t += "project.cmt,v"; if (CmtSystem::test_file (t)) { CmtSystem::basename (subproject, t); if (result != "") result += " "; result += t; } } return (result); } #define V(v) #v //--------------------------------------------------------------------- int main (int /*argc*/, char* argv[]) { clear_cmtcvsinfos (); cmt_string module = argv[1]; int pos = module.find (" "); if (pos != cmt_string::npos) module.erase (pos); module.replace (".cmtcvsinfos/", ""); cout << "#VERSION=[" << VERSION << "]" << endl; cmt_string version = VERSION; version += "/"; pos = module.find (version); if (pos == 0) { const cmt_string null = ""; module.replace (version, null); } pos = module.find (VERSION); if (pos == 0) { module.replace (VERSION, ""); } pos = module.find ("cmtcvstest/"); if (pos == 0) { module.replace ("cmtcvstest/", ""); cmtcvstest = true; //cout << "cmtcvstest=true" << endl; } cout << "#module=[" << module << "]" << endl; if (module == "") { module = "."; } cmt_string tags; cmt_string tags_top; cmt_string cvsversions; cmt_string cvsversions_top; cmt_string dir; get_cvsroot (dir); dir += CmtSystem::file_separator (); dir += module; cmt_string error; StructureType structure = no_structure; //cout << "dir=" << dir << endl; if (CmtSystem::test_directory (dir)) { CmtSystem::cmt_string_vector toptag_list; CmtSystem::cmt_string_vector tag_list; CmtSystem::cmt_string_vector topcvsversion_list; CmtSystem::cmt_string_vector cvsversion_list; structure = get_tags (module, toptag_list, tag_list, topcvsversion_list, cvsversion_list); int i; for (i = 0; i < toptag_list.size (); i++) { const cmt_string& s = toptag_list[i]; const cmt_string& v = topcvsversion_list[i]; if (tags_top != "") tags_top += " "; tags_top += s; if (cvsversions_top != "") cvsversions_top += " "; cvsversions_top += v; } for (i = 0; i < tag_list.size (); i++) { const cmt_string& s = tag_list[i]; const cmt_string& v = cvsversion_list[i]; if (tags != "") tags += " "; tags += s; if (cvsversions != "") cvsversions += " "; cvsversions += v; } } else { error = "### Module "; error += module; error += " not found."; } cmt_string branches; cmt_string subpackages; cmt_string subprojects; if (CmtSystem::test_directory (dir)) { branches = get_branches (module); subpackages = get_subpackages (module); subprojects = get_subprojects (module); } if (error != "") { cout << "error=" << error << endl; } cmt_string structures[] = {"none", "project", "package"}; cout << "structure=" << structures[structure] << endl; cout << "tags_top=" << tags_top << endl; cout << "tags=" << tags << endl; cout << "cvsversions_top=" << cvsversions_top << endl; cout << "cvsversions=" << cvsversions << endl; cout << "branches=" << branches << endl; cout << "subpackages=" << subpackages << endl; cout << "subprojects=" << subprojects << endl; exit (1); }