00001
00002 #include "Package.h"
00003 #include "tree_node.h"
00004
00005 Package::database& Package::get_database ()
00006 {
00007 static database db;
00008
00009 return (db);
00010 }
00011
00012 Package& Package::create (const cmt_string& p,
00013 const cmt_string& v,
00014 const cmt_string& pp,
00015 const cmt_string& a)
00016 {
00017 database& db = get_database ();
00018
00019 bool has_wild_card = false;
00020 cmt_string v_prefix = v;
00021 cmt_regexp* v_exp = 0;
00022 int pos;
00023
00024 if ((pos = v.find ("*")) != cmt_string::npos)
00025 {
00026 has_wild_card = true;
00027 v_prefix.erase (pos);
00028
00029 cmt_string v_text_exp = "^";
00030 v_text_exp += v_prefix;
00031
00032 v_exp = new cmt_regexp (v_text_exp);
00033 }
00034
00035 for (int i = 0; i < db.size (); i++)
00036 {
00037 Package& entry = db[i];
00038 if ((entry.package == p) &&
00039 (entry.path == pp))
00040 {
00041 if (has_wild_card)
00042 {
00043 if (v_exp->match (entry.version))
00044 {
00045 return (entry);
00046 }
00047 }
00048 else
00049 {
00050 if (entry.version == v)
00051 {
00052 return (entry);
00053 }
00054 }
00055 }
00056 }
00057
00058 Package& entry = db.add ();
00059
00060 entry.set (p, v, pp, a);
00061
00062 return (entry);
00063 }
00064
00065 Package::Package ()
00066 {
00067 unreachable = false;
00068 done = false;
00069 node = 0;
00070 m_has_version_directory = true;
00071 m_auto_imports = true;
00072 m_is_public = true;
00073 }
00074
00075 bool Package::is_unreachable () const
00076 {
00077 return (unreachable);
00078 }
00079
00080 void Package::set_unreachable ()
00081 {
00082 unreachable = true;
00083 }
00084
00085 bool Package::is_done () const
00086 {
00087 return (done);
00088 }
00089
00090 void Package::set_done ()
00091 {
00092 done = true;
00093 }
00094
00095 int Package::operator == (const Package& other) const
00096 {
00097 if (package != other.package) return (0);
00098 if (version != other.version) return (0);
00099 if (path != other.path) return (0);
00100 if (area != other.area) return (0);
00101 return (1);
00102 }
00103
00104 int Package::operator != (const Package& other) const
00105 {
00106 const Package& me = *this;
00107 return (!(me == other));
00108 }
00109
00110 const cmt_string& Package::get_name () const
00111 {
00112 return (package);
00113 }
00114
00115 const cmt_string& Package::get_version () const
00116 {
00117 return (version);
00118 }
00119
00120 const cmt_string& Package::get_path () const
00121 {
00122 return (path);
00123 }
00124
00125 const cmt_string& Package::get_dot_name () const
00126 {
00127 return (dot_name);
00128 }
00129
00130 const cmt_string& Package::get_cluster_name () const
00131 {
00132 static const cmt_string top = "top";
00133 if (cluster_name == "") return (top);
00134 return (cluster_name);
00135 }
00136
00137 const cmt_string& Package::get_dot_label () const
00138 {
00139 return (dot_label);
00140 }
00141
00142 cmt_string Package::to_string () const
00143 {
00144 cmt_string result;
00145 result += package;
00146 result += " ";
00147 result += version;
00148 result += " ";
00149 result += path;
00150
00151 return (result);
00152 }
00153
00154 void Package::set_node (tree_node* n)
00155 {
00156 node = n;
00157 }
00158
00159 tree_node* Package::get_node () const
00160 {
00161 return (node);
00162 }
00163
00164 bool Package::has_version_directory () const
00165 {
00166 return (m_has_version_directory);
00167 }
00168
00169 bool Package::auto_imports () const
00170 {
00171 return (m_auto_imports);
00172 }
00173
00174 bool Package::is_public () const
00175 {
00176 return (m_is_public);
00177 }
00178
00179 void Package::set_has_version_directory (bool state)
00180 {
00181 m_has_version_directory = state;
00182 }
00183
00184
00185
00186 void Package::set_auto_imports (bool state)
00187 {
00188 m_auto_imports = state;
00189 }
00190
00191 void Package::set_is_public (bool state)
00192 {
00193 m_is_public = state;
00194 }
00195
00196 void Package::collect_clients (tree_node& node)
00197 {
00198 const database& db = Package::get_database ();
00199 for (int i = 0; i < db.size (); i++)
00200 {
00201 Package& p = db[i];
00202
00203 if (p == *this) continue;
00204
00205 p.check_client (*this, node);
00206 }
00207 }
00208
00209 void Package::check_client (const Package& other, tree_node& node)
00210 {
00211
00212
00213
00214
00215
00216 const Package& me = *this;
00217
00218 if (me == other) return;
00219
00221 cmt_string req;
00222
00223 req = area;
00224 if (req != "") req += CmtSystem::file_separator ();
00225 if (path != "")
00226 {
00227 req += path;
00228 req += CmtSystem::file_separator ();
00229 }
00230 req += package;
00231 req += CmtSystem::file_separator ();
00232 req += version;
00233 req += CmtSystem::file_separator ();
00234 req += "cmt";
00235 req += CmtSystem::file_separator ();
00236 req += "requirements";
00237
00238 if (!CmtSystem::test_file (req))
00239 {
00240 req = area;
00241 if (req != "") req += CmtSystem::file_separator ();
00242 if (path != "")
00243 {
00244 req += path;
00245 req += CmtSystem::file_separator ();
00246 }
00247 req += package;
00248 req += CmtSystem::file_separator ();
00249 req += version;
00250 req += CmtSystem::file_separator ();
00251 req += "cmt";
00252 req += CmtSystem::file_separator ();
00253 req += "requirements";
00254
00255 if (!CmtSystem::test_file (req)) return;
00256 }
00257
00259 static cmt_regexp exp ("^use ");
00260
00266 UseScanner scanner (other, *this, node);
00267
00268
00269
00270 scanner.run (req, exp);
00271
00272
00273 }
00274
00275 void Package::set (const cmt_string& p,
00276 const cmt_string& v,
00277 const cmt_string& pp,
00278 const cmt_string& a)
00279 {
00280 package = p;
00281 version = v;
00282 path = pp;
00283 area = a;
00284
00285 dot_name = "\"";
00286 dot_name += package;
00287 dot_name += "-";
00288 dot_name += version;
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 dot_name += "\"";
00299
00300
00301 cluster_name = "";
00302 if (path != "")
00303 {
00304 cluster_name = path;
00305 cluster_name.replace_all ("/", "_");
00306 cluster_name.replace_all ("\\", "_");
00307 }
00308
00309
00310 dot_label = "";
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 dot_label += package;
00321 if (version != "*")
00322 {
00323 dot_label += "\\n";
00324 dot_label += version;
00325 }
00326 }
00327
00328 void Package::reduce ()
00329 {
00330 if (node == 0) return;
00331
00332
00333 }
00334
00340 UseScanner::UseScanner (const Package& t,
00341 Package& s,
00342 tree_node& node) :
00343 tested (t),
00344 scanned (s),
00345 parent_node (node)
00346 {
00347 }
00348
00349 void UseScanner::begin ()
00350 {
00351 done = false;
00352 }
00353
00359 void UseScanner::filter (const cmt_string& line)
00360 {
00361
00362 if (done) return;
00363
00364 static int level = 0;
00365
00366 CmtSystem::cmt_string_vector words;
00367 CmtSystem::split (line, " ", words);
00368
00369 cmt_string p;
00370 cmt_string v;
00371 cmt_string pp;
00372
00373 if (words.size () > 1) p = words[1];
00374 if (words.size () > 2) v = words[2];
00375 if (words.size () > 3) pp = words[3];
00376
00377 Package& package = Package::create (p, v, pp);
00378 if (package == tested)
00379 {
00380
00381
00382 for (int j = 0; j < level; j++) cout << " ";
00383
00384 cout << " " << scanned.get_name () << endl;
00385
00386 tree_node& node = parent_node.append (scanned);
00387
00392 if (scanned.is_done ()) return;
00393 scanned.set_done ();
00394
00395 done = true;
00396
00397 level++;
00398
00403 scanned.collect_clients (node);
00404
00405 level--;
00406 }
00407 }
00408
00409 void UseScanner::end ()
00410 {
00411 }
00412
00413
00414