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

ProjectFactory Class Reference

#include <cmt_project.h>

Inheritance diagram for ProjectFactory:

Inheritance graph
[legend]
Collaboration diagram for ProjectFactory:

Collaboration graph
[legend]
List of all members.

Public Member Functions

void reset ()
Projectcreate_project (const cmt_string &name, const cmt_string &path, const cmt_string &path_source, Project *parent)

Static Public Member Functions

IProjectFactoryinstance ()

Member Function Documentation

Project * ProjectFactory::create_project const cmt_string name,
const cmt_string path,
const cmt_string path_source,
Project parent
[virtual]
 

Implements IProjectFactory.

Definition at line 191 of file cmt_project.cxx.

References Tag::add(), Project::add(), Project::add_child(), Project::add_parent(), CmtSystem::basename(), CmtSystem::cd(), CmtSystem::cmt_string_vector, CmtSystem::compress_path(), CmtSystem::dirname(), cmt_string::find(), Project::get_cmtpath(), Project::get_cmtpath_pwd(), Cmt::get_debug(), Project::get_name(), ProjectReader::get_project_name(), Cmt::get_quiet(), Project::get_release(), get_release_from_path(), CmtSystem::getenv(), Tag::mark(), SyntaxParser::parse_project_file_text(), CmtSystem::path_separator(), PriorityConfig, Project::projects(), Project::ProjectVector, CmtSystem::pwd(), cmt_string::read(), Awk::run(), CmtError::set(), Project::set_cmtpath(), Project::set_cmtpath_pwd(), Project::set_cmtpath_source(), Project::show_all(), cmt_vector< T >::size(), CmtSystem::split(), CmtSystem::test_file(), and Project::update_strategies_from_children().

00195 {
00196   cmt_string compressed_path = path;
00197   CmtSystem::compress_path (compressed_path);
00198   bool specify_name = (specified_name != "");
00199 
00200   if (Cmt::get_debug ())
00201     {
00202       cout << "Creating project " << path << " with parent " << ((parent==0)? "0" : parent->get_name ()) << endl;
00203       Project::show_all ();
00204     }
00205 
00206   cmt_string sep;
00207   sep = CmtSystem::path_separator ();
00208 
00209   cmt_string cmtprojectpath = CmtSystem::getenv ("CMTPROJECTPATH");
00210   CmtSystem::cmt_string_vector items;
00211   CmtSystem::split (cmtprojectpath, sep, items);
00212 
00213   cmt_string here = CmtSystem::pwd ();
00214   if (!CmtSystem::cd (compressed_path)) return (0);
00215   cmt_string pwd = CmtSystem::pwd ();
00216 
00217   static Project::ProjectVector& Projects = Project::projects ();
00218   
00219   for (int i = 0; i < Projects.size (); i++)
00220     {
00221       Project& p = Projects[i];
00222       
00223       if ((p.get_cmtpath () == compressed_path) ||
00224           (p.get_cmtpath_pwd () == pwd) ||
00225           (specify_name && (p.get_name () == specified_name)))
00226         {
00227           cmt_string r;
00228           cmt_string n;
00229 
00230           get_release_from_path (items, compressed_path, p.get_name (), n, r);
00231 
00232           if (r != p.get_release ())
00233             {
00234               cerr << "#CMT> Project " << p.get_name ()
00235                    << " requested with conflicting releases " << p.get_release () << " and " << r << endl;
00236               CmtError::set (CmtError::project_release_conflict, p.get_name ());
00237             }
00238   
00239           if (parent != 0)
00240             {
00241               p.add_parent (parent);
00242               parent->add_child (&p);
00243 
00244               // Since p is a new parent, we should propagate the settings UP.
00245 
00246               parent->update_strategies_from_children ();
00247             }
00248 
00249           CmtSystem::cd (here);
00250           return (&p);
00251         }
00252     }
00253 
00254 
00255   Project* project = 0;
00256   Project* cmt = 0;
00257   
00258   bool is_current = false;
00259   
00260   cmt_string name = specified_name;
00261   cmt_string project_name;
00262   cmt_string release;
00263 
00264   //
00265   // Figure out if this is the current project
00266   //
00267   if (here.find (pwd) == 0) is_current = true;
00268 
00269   cmt_string text;
00270 
00271   /*
00272     Now Figure out the project name from the project file
00273        or does not specify the project name
00274    */
00275   bool has_project_file = false;
00276 
00277   if (CmtSystem::cd ("cmt") && CmtSystem::test_file (Project::get_project_file_name ()))
00278     {
00279       has_project_file = true;
00280       text.read (Project::get_project_file_name ());
00281 
00282       ProjectReader reader;
00283 
00284       reader.run (text);
00285 
00286       project_name = reader.get_project_name ();
00287     }
00288 
00289   enum
00290     {
00291       without_project_file   = 0x01,
00292       with_project_file      = 0x02,
00293       without_project_name   = 0x04,
00294       with_project_name      = 0x08,
00295       without_specified_name = 0x10,
00296       with_specified_name    = 0x20,
00297       names_mismatch         = 0x40,
00298       names_match            = 0x80
00299     };
00300 
00301   int status = ((has_project_file) ? with_project_file : without_project_file) |
00302     ((has_project_file && (project_name != "")) ? with_project_name : without_project_name) |
00303     ((specify_name) ? with_specified_name : without_specified_name) |
00304     ((specify_name && has_project_file && (project_name == specified_name)) ? names_match : names_mismatch);
00305 
00306   if (source == "default path")
00307     {
00308       name = "CMT";
00309     }
00310   else
00311     {
00312       cmt_string n;
00313           
00314       switch (status)
00315         {
00316         case with_project_file | without_project_name | without_specified_name | names_mismatch:
00317 
00318           // The project is neither specified from the caller nor from the project file
00319 
00320           /*
00321             if (!Cmt::get_quiet ())
00322             {
00323             cerr << "#CMT> Warning: project name unspecified in project file." << endl;
00324             }
00325           */
00326       
00327           get_release_from_path (items, compressed_path, "", name, release);
00328 
00329           break;
00330           
00331         case with_project_file | without_project_name | with_specified_name | names_mismatch:
00332           
00333           // The name is only specified from the caller
00334           // find this specified name in the path
00335           
00336           if (get_release_from_path (items, compressed_path, specified_name, name, release))
00337             {
00338               // The specified name has been found from the path.
00339               // We believe in the release spec.
00340             }
00341           else
00342             {
00343               // The specified name is not in the path.
00344               /*
00345               if (!Cmt::get_quiet ())
00346                 {
00347                   cerr << "#CMT> Warning: specified project name "
00348                        << specified_name
00349                        << " from the caller does not match path." << endl;
00350                 }
00351               */
00352               name = specified_name;
00353             }
00354           
00355           break;
00356           
00357         case with_project_file | with_project_name | with_specified_name | names_match:
00358           
00359           // We have a double specification: from the caller and from the project file.
00360           // And both specifications are consistent.  
00361           
00362           if (get_release_from_path (items, compressed_path, specified_name, name, release))
00363             {
00364               // The specified name has been found from the path.
00365               // We believe in the release spec.
00366             }
00367           else
00368             {
00369               // The specified name is not in the path.
00370               /*
00371               if (!Cmt::get_quiet ())
00372                 {
00373                   cerr << "#CMT> Warning: specified project name "
00374                        << specified_name
00375                        << " from project file and from caller does not match path." << endl;
00376                 }
00377               */
00378               name = specified_name;
00379             }
00380           
00381           break;
00382           
00383         case with_project_file | with_project_name | with_specified_name | names_mismatch:
00384           
00385           // We have a double specification: from the caller and from the project file.
00386           // Specifications are inconsistent!!
00387           
00388           if (!Cmt::get_quiet ())
00389             {
00390               cerr << "#CMT> Warning: specified project name "
00391                    << specified_name
00392                    << " inconsistent with name "
00393                    << project_name
00394                    << " from project file." << endl;
00395             }
00396           
00397           if (get_release_from_path (items, compressed_path, specified_name, n, release))
00398             {
00399               // name from caller wins.
00400             }
00401           else if (get_release_from_path (items, compressed_path, project_name, name, release))
00402             {
00403               // name from project file wins.
00404             }
00405           else
00406             {
00407               // The specified name is not in the path.
00408               
00409               if (!Cmt::get_quiet ())
00410                 {
00411                   cerr << "#CMT> Warning: none of specified project names "
00412                        << specified_name
00413                        << " from graph and "
00414                        << project_name
00415                        << " from project file match path." << endl;
00416                 }
00417 
00418               name = specified_name;
00419             }
00420           
00421           break;
00422           
00423         case with_project_file | with_project_name | without_specified_name | names_mismatch:
00424           
00425           // Project name is specified in the project file but not from the caller.
00426           
00427           if (get_release_from_path (items, compressed_path, project_name, name, release))
00428             {
00429               // The specified name has been found from the path.
00430               // We believe in the release spec.
00431 
00432             }
00433           else
00434             {
00435               // The specified name is not in the path.
00436 
00437               /*
00438               if (!Cmt::get_quiet ())
00439                 {
00440                   cerr << "#CMT> Warning: specified project name "
00441                        << project_name
00442                        << " from project file does not match path." << endl;
00443                 }
00444               */
00445 
00446               name = project_name;
00447             }
00448           
00449           break;
00450           
00451         case without_project_file | without_project_name | without_specified_name | names_mismatch:
00452           
00453           // The project is not specified from the caller and there is no project file
00454           // This corresponds to the backward compatibility
00455           // For the moment, assume /name/release/ structure where release is one level only
00456           
00457           /*
00458             if (!Cmt::get_quiet ())
00459             {
00460             cerr << "#CMT> Warning: project name is not specified "
00461             << " (no project file)." << endl;
00462             }
00463           */
00464           
00465           CmtSystem::basename (compressed_path, release);
00466           CmtSystem::dirname (compressed_path, name);
00467           CmtSystem::basename (name, name);
00468           
00469           break;
00470           
00471         case without_project_file | without_project_name | with_specified_name | names_mismatch:
00472           
00473           // The name is only specified from the caller
00474           // find this specified name in the path
00475           
00476           if (get_release_from_path (items, compressed_path, specified_name, name, release))
00477             {
00478               // The specified name has been found from the path.
00479               // We believe in the release spec.
00480             }
00481           else
00482             {
00483               // The specified name is not in the path.
00484               /*
00485               if (!Cmt::get_quiet ())
00486                 {
00487                   cerr << "#CMT> Warning: specified project name "
00488                        << specified_name
00489                        << " from project graph does not match path." << endl;
00490                 }
00491               */
00492               name = specified_name;
00493             }
00494           
00495           break;
00496         }
00497     }
00498 
00499   project = Project::add (name, release);
00500       
00501   if (parent != 0)
00502     {
00503       project->add_parent (parent);
00504       parent->add_child (project);
00505 
00506       // Since p is a new parent, we should propagate the settings UP.
00507 
00508       parent->update_strategies_from_children ();
00509     }
00510 
00511   if (source == "default path")
00512     {
00513       cmt = project;
00514       is_current = false;
00515     }
00516 
00517   project->set_cmtpath (compressed_path);
00518   project->set_cmtpath_pwd (pwd);
00519   project->set_cmtpath_source (source);
00520 
00521   if (is_current)
00522     {
00523       //
00524       // The current project defines a tag with its name
00525       //
00526 
00527       Tag* tag;
00528       
00529       tag = Tag::add (project->get_name (), PriorityConfig, "PROJECT", 0);
00530       tag->mark ();
00531     }
00532 
00533   if (text != "")
00534     {
00535       // Last step is to parse the project file
00536 
00537       SyntaxParser::parse_project_file_text (text, 
00538                                              Project::get_project_file_name (),
00539                                              project);
00540     }
00541 
00542   CmtSystem::cd (here);
00543 
00544   return (project);
00545 }

IProjectFactory & ProjectFactory::instance  )  [static]
 

Definition at line 85 of file cmt_project.cxx.

Referenced by Cmt::configure_cmt_path(), Cmt::guess_current_project(), and Project::use_action().

00086 {
00087   static ProjectFactory me;
00088   
00089   return (me);
00090 }

void ProjectFactory::reset  )  [virtual]
 

Implements IProjectFactory.

Definition at line 92 of file cmt_project.cxx.

References Project::clear_all().

00093 {
00094   Project::clear_all ();
00095 }


The documentation for this class was generated from the following files:
Generated on Mon May 2 10:25:57 2005 for CMT by doxygen 1.3.5