Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

cmt_generator.cxx

Go to the documentation of this file.
00001 #include <errno.h>
00002 #include <stdio.h>
00003 
00004 #ifndef WIN32
00005 #include <unistd.h>
00006 #endif
00007 
00008 #include "cmt_use.h"
00009 #include "cmt_fragment.h"
00010 #include "cmt_symbol.h"
00011 #include "cmt_system.h"
00012 #include "cmt.h"
00013 #include "cmt_deps_builder.h"
00014 #include "cmt_generator.h"
00015 #include "cmt_constituent.h"
00016 #include "cmt_language.h"
00017 #include "cmt_awk.h"
00018 
00019 static Variable DOCPATH            ("DOCPATH");
00020 static Variable PACKAGEPATH        ("PACKAGEPATH");
00021 static Variable PACKAGEPREFIX      ("PACKAGEPREFIX");
00022 static Variable PACKAGE            ("PACKAGE");
00023 static Variable VERSION            ("VERSION");
00024 static Variable MGRSTYLE           ("MGRSTYLE");
00025 static Variable TITLE              ("TITLE");
00026 static Variable GROUP              ("GROUP");
00027 static Variable CONSTITUENT        ("CONSTITUENT");
00028 static Variable CONSTITUENTSUFFIX  ("CONSTITUENTSUFFIX");
00029 static Variable LIBRARYSUFFIX      ("LIBRARYSUFFIX");
00030 static Variable USER               ("USER");
00031 static Variable DATE               ("DATE");
00032 static Variable PROTOTARGET        ("PROTOTARGET");
00033 static Variable OBJS               ("OBJS");
00034 static Variable CLASSES            ("CLASSES");
00035 static Variable PROTOSTAMPS        ("PROTOSTAMPS");
00036 static Variable NAME               ("NAME");
00037 static Variable FILEPATH           ("FILEPATH");
00038 static Variable FILESUFFIX         ("FILESUFFIX");
00039 static Variable SUFFIX             ("SUFFIX");
00040 static Variable FILENAME           ("FILENAME");
00041 static Variable LINKMACRO          ("LINKMACRO");
00042 static Variable LINE               ("LINE");
00043 static Variable ADDINCLUDE         ("ADDINCLUDE");
00044 static Variable FULLNAME           ("FULLNAME");
00045 static Variable OUTPUTNAME         ("OUTPUTNAME");
00046 static Variable ALLOS9SOURCES      ("ALLOS9SOURCES");
00047 static Variable NODEBUGUSELINKOPTS ("NODEBUGUSELINKOPTS");
00048 static Variable DEBUGUSELINKOPTS   ("DEBUGUSELINKOPTS");
00049 static Variable USEINCLUDES        ("USEINCLUDES");
00050 //------------------------------------------------------------------------
00051 
00052 //------------------------------------------------------------------------
00053 class SourceFile
00054 {
00055 public:
00056   void set (const cmt_string name, Language& language, const cmt_string output)
00057   {
00058     m_name = name;
00059     m_language = &language;
00060     m_output = output;
00061 
00062     char sep = CmtSystem::file_separator ();
00063     if (sep == '/') m_name.replace_all ("\\", sep);
00064     else m_name.replace_all ("/", sep);
00065   }
00066 
00067   cmt_string name () const
00068   {
00069     return (m_name);
00070   }
00071 
00072   Language& language () const
00073   {
00074     return (*m_language);
00075   }
00076 
00077   cmt_string output () const
00078   {
00079     return (m_output);
00080   }
00081 
00082 private:
00083   cmt_string m_name;
00084   Language* m_language;
00085   cmt_string m_output;
00086 };
00087 //------------------------------------------------------------------------
00088 
00089 //------------------------------------------------------------------------
00090 class MakefileGenerator
00091 {
00092 public:
00093 
00094   void analyze_file (const Constituent& constituent,
00095                      const cmt_string& file);
00096   void analyze_document_file (const cmt_string& file,
00097                               const cmt_string& constituent_name,
00098                               const cmt_string& output_suffix);
00099   void reset ();
00100 
00101   void prepare_proto_file (const cmt_string& file);
00102   void proto_file_action (const cmt_string& file, const Constituent& constituent);
00103   void module_file_action (SourceFile& file, const Constituent& constituent);
00104   void java_file_action (SourceFile& file, const Constituent& constituent);
00105 
00106   void fill_outputs ();
00107 
00108   void build_application_makefile (const cmt_string& package,
00109                                    const Constituent& constituent);
00110 
00111   void build_library_makefile (const cmt_string& package,
00112                                const Constituent& constituent);
00113 
00114   void build_document_makefile (const cmt_string& package,
00115                                 const Constituent& constituent);
00116 
00117   void prepare_use_context ();
00118 
00119   void set_full_name (cmt_string& full_name, cmt_string& file);
00120 
00121   cmt_string PACKINCLUDES;
00122   bool PACKOS9;
00123 
00124   cmt_string GENERATOR;
00125   bool is_library;
00126   bool is_application;
00127   bool is_document;
00128   cmt_string srcdir;
00129   cmt_string docdir;
00130   cmt_string cmtdir;
00131   cmt_string incdir;
00132   cmt_string msdevdir;
00133   cmt_string src;
00134   cmt_string doc;
00135   cmt_string inc;
00136   cmt_string mgr;
00137   cmt_string cmt;
00138   cmt_string protos;
00139   cmt_string protonames;
00140   cmt_string os9sources;
00141 
00142   cmt_vector<SourceFile> source_files;
00143 
00144   FILE* output_file;
00145 
00146   DepsBuilder deps_builder;
00147 };
00148 //------------------------------------------------------------------------
00149 
00150 //------------------------------------------------------------------------
00151 static MakefileGenerator Context;
00152 
00153 static FragmentHandle buildproto_fragment ("buildproto");
00154 static FragmentHandle dependencies_fragment ("dependencies");
00155 static FragmentHandle dependencies_and_triggers_fragment ("dependencies_and_triggers");
00156 
00157 static FragmentHandle make_header_fragment ("make_header");
00158 static FragmentHandle library_header_fragment ("library_header");
00159 static FragmentHandle application_header_fragment ("application_header");
00160 static FragmentHandle document_header_fragment ("document_header");
00161 static FragmentHandle java_header_fragment ("java_header");
00162 static FragmentHandle jar_header_fragment ("jar_header");
00163 static FragmentHandle protos_header_fragment ("protos_header");
00164 static FragmentHandle library_fragment ("library");
00165 static FragmentHandle library_no_share_fragment ("library_no_share");
00166 static FragmentHandle application_fragment ("application");
00167 static FragmentHandle jar_fragment ("jar");
00168 static FragmentHandle java_fragment ("java");
00169 static FragmentHandle cleanup_header_fragment ("cleanup_header");
00170 static FragmentHandle cleanup_fragment ("cleanup");
00171 static FragmentHandle cleanup_library_fragment ("cleanup_library");
00172 static FragmentHandle cleanup_application_fragment ("cleanup_application");
00173 static FragmentHandle cleanup_java_fragment ("cleanup_java");
00174 static FragmentHandle cleanup_objects_fragment ("cleanup_objects");
00175 
00176 static FragmentHandle dsw_header_fragment ("dsw_header");
00177 static FragmentHandle dsw_project_fragment ("dsw_project");
00178 static FragmentHandle dsw_all_project_header_fragment ("dsw_all_project_header");
00179 static FragmentHandle dsw_all_project_dependency_fragment ("dsw_all_project_dependency");
00180 static FragmentHandle dsw_all_project_trailer_fragment ("dsw_all_project_trailer");
00181 static FragmentHandle dsw_trailer_fragment ("dsw_trailer");
00182 
00183 static FragmentHandle dsp_all_fragment ("dsp_all");
00184 static FragmentHandle dsp_library_header_fragment ("dsp_library_header");
00185 //static FragmentHandle dsp_shared_library_header_fragment ("dsp_shared_library_header");
00186 static FragmentHandle dsp_application_header_fragment ("dsp_application_header");
00187 static FragmentHandle dsp_windows_header_fragment ("dsp_windows_header");
00188 static FragmentHandle dsp_contents_fragment ("dsp_contents");
00189 static FragmentHandle dsp_trailer_fragment ("dsp_trailer");
00190 
00191 static FragmentHandle make_setup_header_fragment ("make_setup_header");
00192 static FragmentHandle make_setup_fragment ("make_setup");
00193 
00194 static FragmentHandle constituents_header_fragment ("constituents_header");
00195 static FragmentHandle group_fragment ("group");
00196 static FragmentHandle constituent_fragment ("constituent");
00197 static FragmentHandle constituents_trailer_fragment ("constituents_trailer");
00198 
00199 static FragmentHandle readme_header_fragment ("readme_header");
00200 static FragmentHandle readme_fragment ("readme");
00201 static FragmentHandle readme_doc_fragment ("readme_doc");
00202 static FragmentHandle readme_use_fragment ("readme_use");
00203 static FragmentHandle readme_trailer_fragment ("readme_trailer");
00204 
00205 static FragmentHandle check_application_fragment ("check_application");
00206 static FragmentHandle check_java_fragment ("check_java");
00207 static FragmentHandle check_application_header_fragment ("check_application_header");
00208 //------------------------------------------------------------------------
00209 
00210 //--------------------------------------------------
00211 class Packager : public FAwk
00212 {
00213 public:
00214   void begin ();
00215   void filter (const cmt_string& line);
00216   cmt_string& package_name ();
00217 private:
00218   cmt_string m_package_name;
00219 };
00220 //--------------------------------------------------
00221 
00222 //--------------------------------------------------
00223 static void filter_paths (cmt_string& text)
00224 {
00225   static CmtSystem::cmt_string_vector ps;
00226 
00227   CmtSystem::split (text, " ", ps);
00228 
00229   text = "";
00230 
00231   for (int i = 0; i < ps.size (); i++)
00232     {
00233       cmt_string& s = ps[i];
00234 
00235       CmtSystem::compress_path (s);
00236 
00237         //cout << "   filter_paths " << s << endl;
00238 
00239       if (i > 0) text += " ";
00240       text += s;
00241     }
00242 
00243   text.replace_all ("./../src/", "$(src)");
00244   text.replace_all (".\\..\\src\\", "$(src)");
00245   text.replace_all ("../src/", "$(src)");
00246   text.replace_all ("..\\src\\", "$(src)");
00247   text.replace_all ("../doc/", "$(doc)");
00248   text.replace_all ("..\\doc\\", "$(doc)");
00249   text.replace_all ("$(src)$(src)", "$(src)");
00250 }
00251 
00252 static void get_all_files (const cmt_string& full_name, 
00253                            CmtSystem::cmt_string_vector& files)
00254 {
00255   static cmt_string suffix;
00256   static cmt_string name;
00257 
00258   suffix = "";
00259   name = "";
00260 
00261   files.clear ();
00262 
00263   CmtSystem::get_dot_suffix (full_name, suffix);
00264 
00265   if (full_name.find ('*') != cmt_string::npos)
00266     {
00267       CmtSystem::scan_dir (full_name, files);
00268 
00269       if (Cmt::get_debug ())
00270         {
00271           cout << "CMT> full_name=" << full_name <<
00272             " pwd=" << CmtSystem::pwd () << endl;
00273           cout << "CMT> files.size=" <<  files.size () << endl;
00274         }
00275 
00276       for (int j = 0; j < files.size (); j++)
00277         {
00278           cmt_string& n = files[j];
00279           static cmt_string s;
00280 
00281           CmtSystem::get_dot_suffix (n, s);
00282           if (s != suffix) 
00283             {
00284               n = "";
00285             }
00286         }
00287     }
00288   else
00289     {
00290       cmt_string& n = files.add ();
00291 
00292       n = full_name;
00293     }
00294 }
00295 
00296 //--------------------------------------------------
00297 
00298 //--------------------------------------------------
00299 void MakefileGenerator::analyze_file (const Constituent& constituent,
00300                                       const cmt_string& file)
00301 {
00302   static cmt_string suffix;
00303   static cmt_string name;
00304   static cmt_string obj;
00305 
00306   obj = file;
00307 
00308   if (Cmt::get_debug ())
00309     {
00310       cout << "MakefileGenerator::analyze_file> constituent=" << 
00311           constituent.name <<
00312           " file=" << file << endl;
00313     }
00314 
00315   CmtSystem::get_suffix (file, suffix);
00316   CmtSystem::basename (file, suffix, name);
00317 
00318   Language& language = Language::find_with_suffix (suffix);
00319 
00320   if (LINKMACRO == "")
00321     {
00322       LINKMACRO = language.linker;
00323     }
00324 
00325   if (language == "java")
00326     {
00327       static Packager packager;
00328       
00329       obj  = "$(javabin)";
00330       
00331       packager.run (file);
00332       if (packager.package_name () != "")
00333         {
00334           obj += packager.package_name ();
00335           obj += CmtSystem::file_separator ();
00336         }
00337       
00338       obj += name;
00339       obj += ".class";
00340     }
00341   else if (language != Language::null ())
00342     {
00343       obj  = "$(bin)";
00344       if (Cmt::build_nmake ()) obj +=  CONSTITUENT;
00345       if (Cmt::build_nmake ()) obj +=  CmtSystem::file_separator ();
00346       obj += name;
00347       obj += language.output_suffix;
00348       obj += constituent.suffix;
00349       if (Cmt::build_nmake ()) obj += ".obj";
00350       else obj += ".o";
00351  
00352       for (int i = 0; i < language.extra_output_suffixes.size (); i++)
00353         {
00354           cmt_string& extra_suffix = language.extra_output_suffixes[i];
00355 
00356           obj += " $(bin)";
00357           obj += name;
00358           obj += extra_suffix;
00359           obj += language.output_suffix;
00360           obj += constituent.suffix;
00361           if (Cmt::build_nmake ()) obj += ".obj";
00362           else obj += ".o";
00363         }
00364     }
00365   else
00366     {
00367       cout << "#CMT> analyze_file file=" << file << " no language" << endl;
00368     }
00369 
00370   if (Cmt::get_debug ())
00371     {
00372       cout << "MakefileGenerator::analyze_file> constituent=" << 
00373           constituent.name <<
00374           " obj=" << obj << endl;
00375     }
00376 
00377   SourceFile& source = source_files.add ();
00378   source.set (file, language, obj);
00379 }
00380 
00381 //--------------------------------------------------
00382 void MakefileGenerator::analyze_document_file (const cmt_string& file,
00383                                                const cmt_string& constituent_name,
00384                                                const cmt_string& output_suffix)
00385 {
00386   static cmt_string output_dir;
00387   static cmt_string suffix;
00388   static cmt_string name;
00389   static cmt_string obj;
00390 
00391   CmtSystem::dirname (file, output_dir);
00392   output_dir += CmtSystem::file_separator ();
00393 
00394   filter_paths (output_dir);
00395 
00396   CmtSystem::get_suffix (file, suffix);
00397   CmtSystem::basename (file, suffix, name);
00398 
00399   //obj = output_dir;
00400   obj = "$(";
00401   obj += constituent_name;
00402   obj += "_output)";
00403   obj += name;
00404   obj += output_suffix;
00405 
00406   SourceFile& source = source_files.add ();
00407   source.set (file, Language::null (), obj);
00408 }
00409 
00410 //--------------------------------------------------
00411 void MakefileGenerator::reset ()
00412 {
00413   DOCPATH = "";
00414   PACKAGEPATH = "";
00415   PACKAGEPREFIX = "";
00416   PACKAGE = "";
00417   VERSION = "";
00418   MGRSTYLE = "";
00419   TITLE = "";
00420   GROUP = "";
00421   CONSTITUENT = "";
00422   CONSTITUENTSUFFIX = "";
00423   LIBRARYSUFFIX = "";
00424   USER = "";
00425   DATE = "";
00426   PROTOTARGET = "";
00427   OBJS = "";
00428   CLASSES = "";
00429   PROTOSTAMPS = "";
00430   NAME = "";
00431   FILEPATH = "";
00432   FILESUFFIX = "";
00433   SUFFIX = "";
00434   FILENAME = "";
00435   LINKMACRO = "";
00436   LINE = "";
00437   ADDINCLUDE = "";
00438   FULLNAME = "";
00439   OUTPUTNAME = "";
00440   ALLOS9SOURCES = "";
00441   NODEBUGUSELINKOPTS = "";
00442   DEBUGUSELINKOPTS = "";
00443   USEINCLUDES = "";
00444 
00445   PACKINCLUDES = "";
00446   PACKOS9      = false;
00447   GENERATOR    = "";
00448 
00449   is_library     = false;
00450   is_application = false;
00451   is_document    = false;
00452   srcdir       = "";
00453   docdir       = "";
00454   cmtdir       = "";
00455   incdir       = "";
00456   src          = "$(src)";
00457   doc          = "$(doc)";
00458   inc          = "$(inc)";
00459   mgr          = "$(mgr)";
00460   cmt          = "$(cmt)";
00461   protos       = "";
00462   protonames   = "";
00463   os9sources   = "";
00464 
00465   source_files.clear ();
00466 
00467   buildproto_fragment.reset ();
00468   dependencies_fragment.reset ();
00469   dependencies_and_triggers_fragment.reset ();
00470 
00471   make_header_fragment.reset ();
00472   library_header_fragment.reset ();
00473   application_header_fragment.reset ();
00474   document_header_fragment.reset ();
00475   java_header_fragment.reset ();
00476   jar_header_fragment.reset ();
00477   protos_header_fragment.reset ();
00478   library_fragment.reset ();
00479   library_no_share_fragment.reset ();
00480   jar_fragment.reset ();
00481   application_fragment.reset ();
00482   java_fragment.reset ();
00483   cleanup_header_fragment.reset ();
00484   cleanup_fragment.reset ();
00485   cleanup_library_fragment.reset ();
00486   cleanup_application_fragment.reset ();
00487   cleanup_java_fragment.reset ();
00488   cleanup_objects_fragment.reset ();
00489 
00490   dsw_header_fragment.reset ();
00491   dsw_project_fragment.reset ();
00492   dsw_all_project_header_fragment.reset ();
00493   dsw_all_project_dependency_fragment.reset ();
00494   dsw_all_project_trailer_fragment.reset ();
00495   dsw_trailer_fragment.reset ();
00496 
00497   dsp_all_fragment.reset ();
00498   dsp_library_header_fragment.reset ();
00499   //dsp_shared_library_header_fragment.reset ();
00500   dsp_application_header_fragment.reset ();
00501   dsp_windows_header_fragment.reset ();
00502   dsp_contents_fragment.reset ();
00503   dsp_trailer_fragment.reset ();
00504 
00505   make_setup_header_fragment.reset ();
00506   make_setup_fragment.reset ();
00507 
00508   constituents_header_fragment.reset ();
00509   group_fragment.reset ();
00510   constituent_fragment.reset ();
00511   constituents_trailer_fragment.reset ();
00512 
00513   readme_header_fragment.reset ();
00514   readme_fragment.reset ();
00515   readme_doc_fragment.reset ();
00516   readme_use_fragment.reset ();
00517   readme_trailer_fragment.reset ();
00518 
00519   check_application_fragment.reset ();
00520   check_java_fragment.reset ();
00521   check_application_header_fragment.reset ();
00522 
00523   Language::setup_all_fragments ();
00524 
00525   CmtSystem::cd (Cmt::get_current_dir ());
00526 
00527   cmt_string branch = CmtSystem::current_branch ();
00528 
00529   if ((branch == "mgr") || (branch == "cmt"))
00530     {
00531       if (CmtSystem::test_directory ("../src"))
00532         {
00533           srcdir = "..";
00534           srcdir += CmtSystem::file_separator ();
00535           srcdir += "src";
00536           srcdir += CmtSystem::file_separator ();
00537         }
00538       else
00539         {
00540           srcdir = "";
00541         }
00542 
00543       if (CmtSystem::test_directory ("../doc"))
00544         {
00545           docdir = "..";
00546           docdir += CmtSystem::file_separator ();
00547           docdir += "doc";
00548           docdir += CmtSystem::file_separator ();
00549         }
00550       else
00551         {
00552           docdir = "";
00553         }
00554 
00555       if (CmtSystem::test_directory ("../cmt"))
00556         {
00557           cmtdir = "..";
00558           cmtdir += CmtSystem::file_separator ();
00559           cmtdir += "cmt";
00560           cmtdir += CmtSystem::file_separator ();
00561         }
00562       else if (CmtSystem::test_directory ("../mgr"))
00563         {
00564           cmtdir = "..";
00565           cmtdir += CmtSystem::file_separator ();
00566           cmtdir += "mgr";
00567           cmtdir += CmtSystem::file_separator ();
00568         }
00569       else
00570         {
00571           cmtdir = CmtSystem::pwd ();
00572           cmtdir += CmtSystem::file_separator ();
00573         }
00574 
00575       if (CmtSystem::test_directory ("../src"))
00576         {
00577           incdir = "..";
00578           incdir += CmtSystem::file_separator ();
00579           incdir += "src";
00580           incdir += CmtSystem::file_separator ();
00581         }
00582       else
00583         {
00584           incdir = "";
00585         }
00586 
00587 #ifdef WIN32
00588       msdevdir = "..";
00589       msdevdir += CmtSystem::file_separator ();
00590       msdevdir += "Visual";
00591 
00592       if (!CmtSystem::test_directory (msdevdir))
00593         {
00594           CmtSystem::mkdir (msdevdir);
00595         }
00596 
00597       msdevdir += CmtSystem::file_separator ();
00598 #endif
00599 
00600     }
00601   else
00602     {
00603       srcdir = ".";
00604       srcdir += CmtSystem::file_separator ();
00605       docdir = ".";
00606       docdir += CmtSystem::file_separator ();
00607       cmtdir = CmtSystem::pwd ();
00608       cmtdir += CmtSystem::file_separator ();
00609       incdir = ".";
00610       incdir += CmtSystem::file_separator ();
00611 #ifdef WIN32
00612       msdevdir = ".";
00613       msdevdir += CmtSystem::file_separator ();
00614 #endif
00615     }
00616 }
00617 
00618 //--------------------------------------------------
00619 void MakefileGenerator::build_application_makefile (const cmt_string& package,
00620                                                     const Constituent& constituent)
00621 {
00622   build_library_makefile (package, constituent);
00623 }
00624 
00625 //--------------------------------------------------
00626 void MakefileGenerator::prepare_proto_file (const cmt_string& file)
00627 {
00628   static cmt_string name;
00629   static cmt_string pp;
00630 
00631   CmtSystem::name (file, name);
00632 
00633   if (CmtSystem::test_file (file))
00634     {
00635       pp  = incdir;
00636       pp += name;
00637       pp += ".pp";
00638 
00639       if (!CmtSystem::test_file (pp))
00640         {
00641           //Generator::build_prototype (file);
00642         }
00643     }
00644 
00645   protos += " ";
00646   protos += inc;
00647   protos += name;
00648   protos += ".ph";
00649 
00650   protonames += " ";
00651   protonames += name;
00652   protonames += ".ph";
00653 
00654   PROTOSTAMPS += " ";
00655   PROTOSTAMPS += inc;
00656   PROTOSTAMPS += name;
00657   PROTOSTAMPS += ".pp";
00658 }
00659 
00660 //--------------------------------------------------
00661 void MakefileGenerator::proto_file_action (const cmt_string& file, const Constituent& constituent)
00662 {
00663   static cmt_string suffix;
00664 
00665   CmtSystem::dirname (file, FILEPATH.value);
00666   if (FILEPATH.value != "") FILEPATH.value += CmtSystem::file_separator ();
00667 
00668   filter_paths (FILEPATH.value);
00669 
00670   CmtSystem::basename (file, FILENAME.value);
00671   CmtSystem::get_dot_suffix (FILENAME, suffix);
00672 
00673   CmtSystem::basename (FILENAME, suffix, NAME.value);
00674 
00675   buildproto_fragment.copy (output_file, constituent.variables, 3, &NAME, &FILEPATH, &FILENAME);
00676 }
00677 
00678 //--------------------------------------------------
00679 void MakefileGenerator::module_file_action (SourceFile& file, const Constituent& constituent)
00680 {
00681   cmt_string name = file.name ();
00682   Language& language = file.language ();
00683 
00684   static cmt_string suffix;
00685   static cmt_string prefix;
00686   static cmt_string preproc;
00687 
00688   FULLNAME = name;
00689 
00690   CmtSystem::get_dot_suffix (name, suffix);
00691 
00692   CmtSystem::basename (name, suffix, NAME.value);
00693 
00694   CmtSystem::dirname (name, prefix);
00695   CmtSystem::basename (name, FILENAME.value);
00696 
00697   FragmentHandle* fragment;
00698 
00699   if (language != Language::null ())
00700     {
00701       preproc = language.preprocessor_command;
00702       fragment = (is_library) ? &(language.library) : &(language.application);
00703     }
00704   else
00705     {
00706       //
00707       // What happens when the language is not known???
00708       // 
00709       //
00710       preproc = "-I";
00711       fragment = 0;
00712     }
00713 
00714   if ((prefix == "../src") || (prefix == "..\\src"))
00715     {
00716       ADDINCLUDE = "";
00717     }
00718   else if (prefix != "")
00719     {
00720       ADDINCLUDE  = preproc;
00721       ADDINCLUDE += prefix;
00722     }
00723 
00724   if (!CmtSystem::test_file (name))
00725     {
00726       cout << "#CMT> Warning : Source file " << name << " not found" << endl;
00727     }
00728 
00729   FILEPATH = prefix;
00730   if (FILEPATH.value != "") FILEPATH.value += CmtSystem::file_separator ();
00731   filter_paths (FILEPATH.value);
00732 
00733   LINE = FULLNAME.value;
00734   LINE += " ";
00735 
00736   filter_paths (FULLNAME.value);
00737   filter_paths (LINE.value);
00738 
00739   CmtSystem::get_suffix (name, FILESUFFIX.value);
00740 
00741   if (fragment != 0)
00742     {
00743       fragment->copy (output_file, constituent.variables, 10,
00744                       &CONSTITUENT, &CONSTITUENTSUFFIX, &FILENAME, &NAME, &LINE,
00745                       &ADDINCLUDE, &FULLNAME, &FILEPATH, &FILESUFFIX, &PACKAGE);
00746     }
00747 
00748   if (PACKOS9)
00749     {
00750       os9sources += LINE;
00751       os9sources += " ";
00752     }
00753 }
00754 
00755 //--------------------------------------------------
00756 void MakefileGenerator::java_file_action (SourceFile& file, const Constituent& constituent)
00757 {
00758   static cmt_string suffix;
00759 
00760   FULLNAME = file.name ();
00761   OUTPUTNAME = file.output ();
00762 
00763   CmtSystem::get_dot_suffix (FULLNAME, suffix);
00764   
00765   CmtSystem::basename (FULLNAME, suffix, NAME.value);
00766   CmtSystem::basename (FULLNAME, FILENAME.value);
00767   
00768   if (CmtSystem::test_file (FULLNAME))
00769     {
00770       java_fragment.copy (output_file, constituent.variables, 5, &NAME,
00771                           &FULLNAME, &OUTPUTNAME,
00772                           &CONSTITUENT, &CONSTITUENTSUFFIX);
00773     }
00774   else
00775     {
00776       cout << "#CMT> Warning : file " << FULLNAME << " not found" << endl;
00777     }
00778 }
00779 
00780 //--------------------------------------------------
00781 void MakefileGenerator::fill_outputs ()
00782 {
00783   bool first = true;
00784 
00785   OBJS = "";
00786 
00787   for (int i = 0; i < source_files.size (); i++)
00788     {
00789       const SourceFile& file = source_files[i];
00790       const cmt_string output = file.output ();
00791 
00792       if (output != "")
00793         {
00794           if (first)
00795             {
00796               first = false;
00797             }
00798           else
00799             {
00800               OBJS += " ";
00801             }
00802 
00803           OBJS += output;
00804         }
00805 
00806       if (Cmt::get_debug ())
00807         {
00808           cout << "MakefileGenerator::fill_outputs> output=" << output << " OBJS=" << OBJS << endl;
00809         }
00810 
00811     }
00812 
00813   if (Cmt::get_debug ())
00814     {
00815       cout << "MakefileGenerator::fill_outputs> OBJS=" << OBJS << endl;
00816     }
00817 
00818 }
00819 
00820 //--------------------------------------------------
00821 void MakefileGenerator::build_library_makefile (const cmt_string& package,
00822                                                 const Constituent& constituent)
00823 {
00824   static cmt_string lib;
00825   static cmt_string allsources;
00826   static cmt_string file;
00827   static cmt_string full_name;
00828   static cmt_string compressed_name;
00829   static cmt_string suffix;
00830   int i;
00831   bool need_prototypes;
00832 
00833   source_files.clear ();
00834 
00835   need_prototypes = constituent.need_prototypes;
00836 
00837   cout << TITLE << " " << CONSTITUENT << endl;
00838 
00839   lib  = "$(";
00840   lib += CONSTITUENT;
00841   lib += "lib)";
00842 
00843   //
00844   // Prepare the include paths
00845   //
00846 
00847   const CmtSystem::cmt_string_vector& includes = constituent.includes;
00848 
00849   for (i = 0; i < includes.size (); i++)
00850     {
00851       const cmt_string& subdir = includes[i];
00852 
00853       PACKINCLUDES += " -I";
00854       PACKINCLUDES += subdir;
00855     }
00856 
00857   //
00858   // Scan the sources.
00859   //
00860 
00861   const CmtSystem::cmt_string_vector& sources = constituent.modules;
00862 
00863   for (i = 0; i < sources.size (); i++)
00864     {
00865       file = sources[i];
00866 
00867       set_full_name (full_name, file);
00868       if (full_name == "") continue;
00869 
00870       CmtSystem::compress_path (full_name, compressed_name);
00871       full_name = compressed_name;
00872 
00873       static CmtSystem::cmt_string_vector files;
00874 
00875       get_all_files (full_name, files);
00876 
00877       for (int j = 0; j < files.size (); j++)
00878         {
00879           const cmt_string& name = files[j];
00880 
00881           if (name != "") 
00882             {
00883               analyze_file (constituent, name);
00884             }
00885         }
00886     }
00887 
00888   fill_outputs ();
00889 
00890   prepare_use_context ();
00891 
00892   DATE = CmtSystem::now ();
00893   USER = CmtSystem::user ();
00894   PACKAGE = package;
00895 
00896   make_header_fragment.copy (output_file, constituent.variables, 6, 
00897                              &TITLE, &CONSTITUENT, &CONSTITUENTSUFFIX,
00898                              &USER, &DATE, &PACKAGE);
00899 
00900   if (need_prototypes)
00901     {
00902       need_prototypes = false;
00903 
00904       for (i = 0; i < source_files.size (); i++)
00905         {
00906           const SourceFile& file = source_files[i];
00907           Language& language = file.language ();
00908           if (language.prototypes)
00909             {
00910               need_prototypes = true;
00911               break;
00912             }
00913         }
00914     }
00915 
00916   //-------------------------------------------
00917   //
00918   // Specific targets (application, library or java)
00919   // Prepare in case prototype files are needed
00920   //
00921   //-------------------------------------------
00922 
00923   PROTOTARGET = "";
00924 
00925   //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
00926   if (need_prototypes)
00927     {
00928       PROTOTARGET = CONSTITUENT;
00929       PROTOTARGET += "PROTOS";
00930     }
00931 
00932   if (LINKMACRO == "java")
00933     {
00934       if (is_library)
00935         {
00936           jar_header_fragment.copy (output_file, constituent.variables, 3, 
00937                                     &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
00938         }
00939       else
00940         {
00941           java_header_fragment.copy (output_file, constituent.variables, 3, 
00942                                      &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
00943         }
00944     }
00945   else
00946     {
00947       if (is_library)
00948         {
00949           library_header_fragment.copy (output_file, constituent.variables, 3,
00950                                         &CONSTITUENT,
00951                                         &CONSTITUENTSUFFIX,
00952                                         &PROTOTARGET);
00953         }
00954       else
00955         {
00956           application_header_fragment.copy (output_file, constituent.variables, 3,
00957                                             &CONSTITUENT, &CONSTITUENTSUFFIX, 
00958                                             &PROTOTARGET);
00959         }
00960     }
00961 
00962 
00963   //----------------------------------------------------
00964   //
00965   // Preparing prototype files.
00966   //
00967   //----------------------------------------------------
00968 
00969   //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
00970   if (need_prototypes)
00971     {
00972       for (i = 0; i < source_files.size (); i++)
00973         {
00974           const SourceFile& file = source_files[i];
00975           Language& language = file.language ();
00976           if (language.prototypes)
00977             {
00978               prepare_proto_file (file.name ());
00979             }
00980         }
00981 
00982       if (PROTOSTAMPS != "")
00983         {
00984           protos_header_fragment.copy (output_file, constituent.variables, 3, 
00985                                        &CONSTITUENT, &CONSTITUENTSUFFIX, &PROTOSTAMPS);
00986         }
00987 
00988       if (protonames != "")
00989         {
00990           for (i = 0; i < source_files.size (); i++)
00991             {
00992               const SourceFile& file = source_files[i];
00993               Language& language = file.language ();
00994               if (language.prototypes)
00995                 {
00996                   proto_file_action (file.name (), constituent);
00997                 }
00998             }
00999         }
01000     }
01001 
01002   //----------------------------------------------------
01003   //
01004   // Preparing the library.
01005   //
01006   //----------------------------------------------------
01007 
01008   if (OBJS != "")
01009     {
01010       if (LINKMACRO == "java")
01011         {
01012           if (is_library)
01013             {
01014               cmt_string classes = OBJS.value;
01015 
01016               classes.replace_all ("$(javabin)", "");
01017               classes.replace_all (srcdir.c_str (), "");
01018 
01019               CLASSES = classes;
01020 
01021               jar_fragment.copy (output_file, constituent.variables, 4, 
01022                                  &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS, &CLASSES);
01023             }
01024         }
01025       else
01026         {
01027           if (is_library)
01028             {
01029               if (constituent.no_share)
01030                 {
01031                   library_no_share_fragment.copy (output_file, constituent.variables, 3, 
01032                                                   &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
01033                 }
01034               else
01035                 {
01036                   library_fragment.copy (output_file, constituent.variables, 3, 
01037                                          &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
01038                 }
01039             }
01040           else
01041             {
01042               application_fragment.copy (output_file, constituent.variables, 4,
01043                                          &CONSTITUENT, &CONSTITUENTSUFFIX, 
01044                                          &OBJS, &LINKMACRO);
01045             }
01046         }
01047     }
01048 
01049   LINE = "";
01050   for (i = 0; i < sources.size (); i++)
01051     {
01052       file = sources[i];
01053 
01054       set_full_name (full_name, file);
01055       if (full_name == "") continue;
01056 
01057       static CmtSystem::cmt_string_vector files;
01058       get_all_files (full_name, files);
01059 
01060       int count = 0;
01061 
01062       for (int j = 0; j < files.size (); j++)
01063         {
01064           cmt_string& n = files[j];
01065           if (n != "") count++;
01066         }
01067 
01068       if (count > 0)
01069         {
01070           LINE += full_name;
01071           LINE += " ";
01072         }
01073     }
01074 
01075   filter_paths (LINE.value);
01076 
01077   if (constituent.build_triggers)
01078     {
01079       dependencies_and_triggers_fragment.copy (output_file, 
01080                                                constituent.variables, 3,
01081                                                &CONSTITUENT, 
01082                                                &CONSTITUENTSUFFIX, 
01083                                                &LINE);
01084     }
01085   else
01086     {
01087       dependencies_fragment.copy (output_file, 
01088                                   constituent.variables, 3,
01089                                   &CONSTITUENT, 
01090                                   &CONSTITUENTSUFFIX, 
01091                                   &LINE);
01092     }
01093 
01094   //----------------------------------------------------
01095   //
01096   // Building actual individual targets.
01097   //
01098   //----------------------------------------------------
01099 
01100   for (i = 0; i < source_files.size (); i++)
01101     {
01102       SourceFile& file = source_files[i];
01103       Language& language = file.language ();
01104 
01105       if (language == "java")
01106         {
01107           java_file_action (file, constituent);
01108         }
01109       else
01110         {
01111           module_file_action (file, constituent);
01112         }
01113     }
01114 
01115   if (PACKOS9)
01116     {
01117       if (os9sources != "")
01118         {
01119           //
01120           // Generate transfers to the OS9 area.
01121           //
01122 
01123           ALLOS9SOURCES = "";
01124           allsources = "";
01125         }
01126     }
01127 
01128   /*
01129     for file in `cmt_sort_line.csh ${os9sources}` ; do
01130     if test `echo ${file} | grep '$(src)'` ; then
01131     name=`echo ${file} | sed 's#$(src)##'`
01132     ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
01133     allsources="${allsources} ${file}"
01134     elif test `echo ${file} | grep '$(inc)'` ; then
01135     name=`echo ${file} | sed 's#$(inc)##'`
01136     ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
01137     allsources="${allsources} ${file}"
01138     fi
01139     done
01140 
01141     if test ! "${ALLOS9SOURCES}" = "" ; then
01142 
01143     sed -e "`subs_vars ALLOS9SOURCES`" \
01144     ${os9_header_fragment} \
01145     >>${output}
01146 
01147     for FULLNAME in ${allsources} ; do
01148 
01149     NAME=`echo ${FULLNAME} | sed -e 's#$(src)##' -e 's#$(inc)##'`
01150 
01151     sed -e "`subs_vars NAME FULLNAME`" \
01152     ${os9_fragment} \
01153     >>${output}
01154 
01155     done
01156     fi
01157     fi
01158     fi
01159   */
01160 
01161   //
01162   //  Generate package cleanup operations.
01163   //
01164 
01165   cleanup_header_fragment.copy (output_file, constituent.variables, 2, 
01166                                 &CONSTITUENT, &CONSTITUENTSUFFIX);
01167 
01168   //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
01169   if (need_prototypes)
01170     {
01171       if (protos != "")
01172         {
01173           FULLNAME = protos;
01174           cleanup_fragment.copy (output_file, constituent.variables, 1, &FULLNAME);
01175           FULLNAME = PROTOSTAMPS;
01176           cleanup_fragment.copy (output_file, constituent.variables, 1, &FULLNAME);
01177         }
01178     }
01179 
01180   if (LINKMACRO == "java")
01181     {
01182       cleanup_java_fragment.copy (output_file, constituent.variables, 1, &OBJS);
01183 
01184       if (!is_library)
01185         {
01186           if (constituent.need_check)
01187             {
01188               check_java_fragment.copy (output_file, constituent.variables, 2, 
01189                                         &CONSTITUENT, &CONSTITUENTSUFFIX);
01190             }
01191         }
01192     }
01193   else
01194     {
01195       if (is_library)
01196         {
01197           cleanup_library_fragment.copy (output_file, constituent.variables, 2, 
01198                                          &CONSTITUENT, &CONSTITUENTSUFFIX);
01199         }
01200       else
01201         {
01202           cleanup_application_fragment.copy (output_file, constituent.variables, 2, 
01203                                              &CONSTITUENT, &CONSTITUENTSUFFIX);
01204           if (OBJS != "")
01205             {
01206               cleanup_objects_fragment.copy (output_file, constituent.variables, 3, 
01207                                              &OBJS, &CONSTITUENT, &CONSTITUENTSUFFIX);
01208             }
01209 
01210           if (constituent.need_check)
01211             {
01212               check_application_fragment.copy (output_file, constituent.variables, 2, 
01213                                                &CONSTITUENT, &CONSTITUENTSUFFIX);
01214             }
01215         }
01216     }
01217 }
01218 
01219 //--------------------------------------------------
01220 void MakefileGenerator::build_document_makefile (const cmt_string& package,
01221                                                  const Constituent& constituent)
01222 {
01223   static cmt_string names;
01224   static cmt_string output_dir;
01225   static cmt_string name;
01226   static cmt_string full_name;
01227   static cmt_string suffix;
01228   static cmt_string output_suffix;
01229   static cmt_string fragment_suffix;
01230   int i;
01231 
01232   cout << TITLE << " " << CONSTITUENT << endl;
01233 
01234   //
01235   // Prepare the include paths.
01236   //
01237 
01238   const CmtSystem::cmt_string_vector& includes = constituent.includes;
01239 
01240   for (i = 0; i < includes.size (); i++)
01241     {
01242       const cmt_string& subdir = includes[i];
01243 
01244       PACKINCLUDES += " -I";
01245       PACKINCLUDES += subdir;
01246     }
01247 
01248   //
01249   // Get the fragment associated with the document style
01250   //
01251 
01252   FragmentHandle fragment (GENERATOR);
01253 
01254   fragment_suffix = fragment.suffix ();
01255 
01256   output_suffix = ".";
01257 
01258   if (fragment_suffix == "")
01259     {
01260       output_suffix += fragment.name ();
01261     }
01262   else
01263     {
01264       output_suffix += fragment_suffix;
01265     }
01266 
01267   //
01268   // Scan the sources.
01269   //
01270 
01271   const CmtSystem::cmt_string_vector& sources = constituent.modules;
01272 
01273   for (i = 0; i < sources.size (); i++)
01274     {
01275       cmt_string& file = sources[i];
01276 
01277       set_full_name (full_name, file);
01278       if (full_name == "") continue;
01279 
01280       static CmtSystem::cmt_string_vector files;
01281 
01282       get_all_files (full_name, files);
01283 
01284       for (int j = 0; j < files.size (); j++)
01285         {
01286           const cmt_string& name = files[j];
01287 
01288           if (name != "") 
01289             {
01290               analyze_document_file (name, constituent.name, output_suffix);
01291             }
01292         }
01293     }
01294 
01295   fill_outputs ();
01296 
01297   prepare_use_context ();
01298 
01299   DATE = CmtSystem::now ();
01300   USER = CmtSystem::user ();
01301   PACKAGE = package;
01302 
01303   make_header_fragment.copy (output_file, constituent.variables, 6,
01304                              &TITLE, &CONSTITUENT, &CONSTITUENTSUFFIX,
01305                              &USER, &DATE, &PACKAGE);
01306 
01307   const cmt_string& header = fragment.header ();
01308 
01309   //
01310   // If the document type specifies a header, use it . 
01311   // otherwise, use the default document header fragment.
01312   //
01313   if (header != "")
01314     {
01315       FragmentHandle header_fragment (header);
01316       header_fragment.copy (output_file, constituent.variables, 3, 
01317                             &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
01318     }
01319   else
01320     {
01321       document_header_fragment.copy (output_file, constituent.variables, 3, 
01322                                      &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
01323     }
01324 
01325   if (fragment.need_dependencies ())
01326     {
01327       LINE = "";
01328       for (i = 0; i < sources.size (); i++)
01329         {
01330           cmt_string& file = sources[i];
01331 
01332           set_full_name (full_name, file);
01333           if (full_name == "") continue;
01334 
01335           static CmtSystem::cmt_string_vector files;
01336           get_all_files (full_name, files);
01337 
01338           int count = 0;
01339 
01340           for (int j = 0; j < files.size (); j++)
01341             {
01342               cmt_string& n = files[j];
01343               if (n != "") count++;
01344             }
01345 
01346           if (count > 0)
01347             {
01348               LINE += full_name;
01349               LINE += " ";
01350             }
01351         }
01352 
01353       filter_paths (LINE.value);
01354 
01355       dependencies_fragment.copy (output_file, constituent.variables, 3, 
01356                                   &CONSTITUENT, &CONSTITUENTSUFFIX, &LINE);
01357     }
01358   else
01359     {
01360       for (i = 0; i < sources.size (); i++)
01361         {
01362           cmt_string& file = sources[i];
01363           
01364           set_full_name (full_name, file);
01365           if (full_name == "") continue;
01366           
01367           static CmtSystem::cmt_string_vector files;
01368           
01369           get_all_files (full_name, files);
01370           
01371           for (int j = 0; j < files.size (); j++)
01372             {
01373               const cmt_string& name = files[j];
01374               
01375               if (name != "") 
01376                 {
01377                   static cmt_string s;
01378                   static cmt_string n;
01379                   
01380                   CmtSystem::get_dot_suffix (name, s);
01381                   CmtSystem::basename (name, s, n);
01382                   CmtSystem::get_suffix (name, s);
01383                   
01384                   fprintf (output_file, "%s_%s_dependencies = %s\n",
01385                            n.c_str (),
01386                            s.c_str (),
01387                            name.c_str ());
01388                 }
01389             }
01390         }
01391     }
01392   
01393   SUFFIX = fragment_suffix;
01394   for (i = 0; i < source_files.size (); i++)
01395     {
01396       SourceFile& file = source_files[i];
01397       const cmt_string& file_name = file.name ();
01398       FULLNAME = file_name;
01399       CmtSystem::get_dot_suffix (file_name, suffix);
01400       CmtSystem::basename (file_name, suffix, NAME.value);
01401       CmtSystem::dirname (file_name, FILEPATH.value);
01402       if (FILEPATH.value != "") FILEPATH.value += CmtSystem::file_separator ();
01403       filter_paths (FILEPATH.value);
01404       CmtSystem::basename (file_name, FILENAME.value);
01405       CmtSystem::get_dot_suffix (FILENAME.value, FILESUFFIX.value);
01406 
01407       if (!CmtSystem::test_file (file_name))
01408         {
01409           cout << "#CMT> Warning : Source file " << file_name << " not found" << endl;
01410         }
01411 
01412       filter_paths (FULLNAME.value);
01413 
01414       fragment.copy (output_file, constituent.variables, 8,
01415                      &FILEPATH, &SUFFIX,
01416                      &CONSTITUENT, &CONSTITUENTSUFFIX, &FILENAME,
01417                      &NAME, &FULLNAME, &FILESUFFIX);
01418     }
01419 
01420   const cmt_string& trailer = fragment.trailer ();
01421   if (trailer != "")
01422     {
01423       FragmentHandle trailer_fragment (trailer);
01424       trailer_fragment.copy (output_file, constituent.variables, 3, 
01425                              &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
01426     }
01427 
01428   //
01429   //  Generate package cleanup operations.
01430   //
01431 
01432   cleanup_header_fragment.copy (output_file, constituent.variables, 2, 
01433                                 &CONSTITUENT, &CONSTITUENTSUFFIX);
01434 }
01435 
01436 //--------------------------------------------------
01437 void MakefileGenerator::prepare_use_context ()
01438 {
01439   cmt_string path;
01440   cmt_string substitution;
01441 
01442   Use* use = &Use::current ();
01443 
01444   deps_builder.clear ();
01445 
01446   if (use->include_path != "none")
01447     {
01448       if (use->include_path == "")
01449         {
01450           deps_builder.add (incdir, "$(src)");
01451         }
01452       else
01453         {
01454           substitution = use->include_path;
01455           
01456           path = substitution;
01457           Symbol::expand (path);
01458           
01459           if (CmtSystem::file_separator () == '/')
01460             {
01461               path.replace_all ("\\", "/");
01462               path.replace_all ("//", "/");
01463             }
01464           else
01465             {
01466               path.replace_all ("/", "\\");
01467               path.replace_all ("\\\\", "\\");
01468             }
01469         }
01470       
01471       deps_builder.add (path, substitution);
01472     }
01473 
01474   deps_builder.add_includes (*use);
01475 
01476   Use::UsePtrVector& uses = Use::uses ();
01477 
01478   if (uses.size () > 0)
01479     {
01480       int number;
01481 
01482       for (number = 0; number < uses.size (); number++)
01483         {
01484           use = uses[number];
01485           if (use->discarded) continue;
01486 
01487           if (use->real_path != "")
01488             {
01489               if (use->include_path != "none")
01490                 {
01491                   if (use->include_path == "")
01492                     {
01493                       path = use->real_path;
01494                       path += CmtSystem::file_separator ();
01495                       path += use->package;
01496                       path += CmtSystem::file_separator ();
01497                       path += use->version;
01498                       path += CmtSystem::file_separator ();
01499                       path += "src";
01500 
01501                       substitution = "$(";
01502                       substitution += use->prefix;
01503                       substitution += "ROOT)";
01504                       substitution += CmtSystem::file_separator ();
01505                       substitution += "src";
01506                       substitution += CmtSystem::file_separator ();
01507                     }
01508                   else
01509                     {
01510                       substitution = use->include_path;
01511 
01512                       path = substitution;
01513                       Symbol::expand (path);
01514 
01515                       if (CmtSystem::file_separator () == '/')
01516                         {
01517                           path.replace_all ("\\", "/");
01518                           path.replace_all ("//", "/");
01519                         }
01520                       else
01521                         {
01522                           path.replace_all ("/", "\\");
01523                           path.replace_all ("\\\\", "\\");
01524                         }
01525                     }
01526 
01527                   deps_builder.add (path, substitution);
01528                 }
01529 
01530               deps_builder.add_includes (*use);
01531             }
01532         }
01533     }
01534 }
01535 
01536 //--------------------------------------------------
01537 void MakefileGenerator::set_full_name (cmt_string& full_name, cmt_string& file)
01538 {
01539   full_name = "";
01540 
01541   Symbol::expand (file);
01542 
01543   if (file == "") return;
01544   
01545   if (!CmtSystem::absolute_path (file))
01546     {
01547       full_name = srcdir;
01548       if (full_name != "") full_name += CmtSystem::file_separator ();
01549     }
01550   
01551   full_name += file;
01552 
01553   char sep = CmtSystem::file_separator ();
01554   if (sep == '/') 
01555     {
01556       full_name.replace_all ("\\", sep);
01557       full_name.replace_all ("//", "/");
01558     }
01559   else
01560     {
01561       full_name.replace_all ("/", sep);
01562       full_name.replace_all ("\\\\", "\\");
01563     }
01564 }
01565 
01566 //--------------------------------------------------
01567 void Generator::commit (const cmt_string& name)
01568 {
01569   static cmt_string old;
01570   static cmt_string backup;
01571 
01572   old = name;
01573 
01574   int pos = old.find_last_of ("new");
01575   old.erase (pos);
01576 
01577   if (CmtSystem::test_file (old))
01578     {
01579       backup = old;
01580       backup += "sav";
01581 
01582       unlink (backup.c_str ());
01583       rename (old.c_str (), backup.c_str ());
01584     }
01585 
01586   rename (name.c_str (), old.c_str ());
01587 }
01588 
01589 //--------------------------------------------------
01590 void Generator::check (const cmt_string& name)
01591 {
01592   static cmt_string old;
01593   static cmt_string backup;
01594 
01595   old = name;
01596 
01597   int pos = old.find_last_of ("new");
01598   old.erase (pos);
01599 
01600   if (!CmtSystem::compare_files (old, name))
01601     {
01602       backup = old;
01603       backup += "sav";
01604 
01605       unlink (backup.c_str ());
01606       rename (old.c_str (), backup.c_str ());
01607       rename (name.c_str (), old.c_str ());
01608     }
01609   else
01610     {
01611       unlink (name);
01612     }
01613 }
01614 
01615 //--------------------------------------------------
01616 int Generator::build_msdev_workspace (const Constituent::ConstituentVector& constituents)
01617 {
01618   Context.reset ();
01619 
01620   const cmt_string& package = Cmt::get_current_package ();
01621 
01622   cmt_string output = Context.msdevdir + package + ".dswnew";
01623 
01624   Context.output_file = fopen (output.c_str (), "wb");
01625   if (Context.output_file != NULL)
01626     {
01627       PACKAGE = package;
01628       dsw_header_fragment.wincopy (Context.output_file, 1, &PACKAGE);
01629 
01630       int i;
01631 
01632       dsw_all_project_header_fragment.wincopy (Context.output_file,
01633                                                1, &PACKAGE);
01634 
01635       for (i = 0; i < constituents.size (); i++)
01636         {
01637           const Constituent& constituent = constituents[i];
01638 
01639           if (constituent.type == Library)
01640             {
01641               CONSTITUENT = constituent.name;
01642               CONSTITUENTSUFFIX = constituent.suffix;
01643               dsw_all_project_dependency_fragment.wincopy (Context.output_file, constituent.variables, 3,
01644                                                            &PACKAGE,
01645                                                            &CONSTITUENT, 
01646                                                            &CONSTITUENTSUFFIX);
01647             }
01648           else
01649             {
01650               CONSTITUENT = constituent.name;
01651               CONSTITUENTSUFFIX = constituent.suffix;
01652               dsw_all_project_dependency_fragment.wincopy (Context.output_file, constituent.variables, 3,
01653                                                            &PACKAGE,
01654                                                            &CONSTITUENT, 
01655                                                            &CONSTITUENTSUFFIX);
01656             }
01657 
01658         }
01659 
01660       dsw_all_project_trailer_fragment.wincopy (Context.output_file,
01661                                                 1, &PACKAGE);
01662 
01663       for (i = 0; i < constituents.size (); i++)
01664         {
01665           const Constituent& constituent = constituents[i];
01666 
01667           if (constituent.type == Library)
01668             {
01669               CONSTITUENT = constituent.name;
01670               CONSTITUENTSUFFIX = constituent.suffix;
01671               dsw_project_fragment.wincopy (Context.output_file,
01672                                             constituent.variables, 3,
01673                                             &PACKAGE,
01674                                             &CONSTITUENT, 
01675                                             &CONSTITUENTSUFFIX);
01676             }
01677           else
01678             {
01679               CONSTITUENT = constituent.name;
01680               CONSTITUENTSUFFIX = constituent.suffix;
01681               dsw_project_fragment.wincopy (Context.output_file, constituent.variables, 3, 
01682                                             &PACKAGE,
01683                                             &CONSTITUENT, 
01684                                             &CONSTITUENTSUFFIX);
01685             }
01686         }
01687 
01688       dsw_trailer_fragment.wincopy (Context.output_file, 1, &PACKAGE);
01689 
01690       fclose (Context.output_file);
01691 
01692       //--- Complete the operation --------------
01693 
01694       commit (output);
01695     }
01696 
01697   output = Context.msdevdir + "all.dspnew";
01698 
01699   Context.output_file = fopen (output.c_str (), "wb");
01700   if (Context.output_file != NULL)
01701     {
01702       dsp_all_fragment.wincopy (Context.output_file, 1, &PACKAGE);
01703       fclose (Context.output_file);
01704 
01705       //--- Complete the operation --------------
01706 
01707       commit (output);
01708     }
01709 
01710   return (0);
01711 }
01712 
01713 //--------------------------------------------------
01714 int Generator::build_msdev (const Constituent& constituent)
01715 {
01716   Context.reset ();
01717 
01718   const cmt_string& package = Cmt::get_current_package ();
01719   static cmt_string file;
01720   static cmt_string full_name;
01721   static cmt_string suffix;
01722 
01723   int i;
01724 
01725   CONSTITUENT = constituent.name;
01726   CONSTITUENTSUFFIX = constituent.suffix;
01727 
01728   for (i = 0; i < constituent.includes.size (); i++)
01729     {
01730       const cmt_string& include = constituent.includes[i];
01731       Context.PACKINCLUDES += " -I" + include;
01732     }
01733 
01734   switch (constituent.type)
01735     {
01736     case Application:
01737       Context.is_application = true;
01738       TITLE = "Application";
01739       break;
01740     case Library:
01741       Context.is_library = true;
01742       TITLE = "Library";
01743       break;
01744     case Document:
01745       Context.is_document = true;
01746       Context.GENERATOR = constituent.generator;
01747       TITLE = "Document";
01748       break;
01749     }
01750 
01751   Context.PACKOS9 = constituent.need_OS9;
01752 
01753   const CmtSystem::cmt_string_vector& sources = constituent.modules;
01754 
01755   //--- Build the constituents fragment -----
01756   cmt_string output;
01757   cmt_string output_s;
01758 
01759   FILE* output_file = NULL;
01760   FILE* output_file_s = NULL;
01761 
01762   output = Context.msdevdir + CONSTITUENT + ".dspnew";
01763   output_file = fopen (output.c_str (), "wb");
01764 
01765   if ((output_file == NULL) && (output_file_s == NULL)) return (0);
01766 
01767   PACKAGE = package;
01768 
01769   if (Context.is_library)
01770     {
01771       if (constituent.no_share)
01772         {
01773           LIBRARYSUFFIX = "lib";
01774         }
01775       else
01776         {
01777           LIBRARYSUFFIX = "arc";
01778         }
01779 
01780       dsp_library_header_fragment.wincopy (output_file, constituent.variables, 4,
01781                                            &PACKAGE,
01782                                            &CONSTITUENT, 
01783                                            &CONSTITUENTSUFFIX, 
01784                                            &LIBRARYSUFFIX);
01785     }
01786   else
01787     {
01788       if (constituent.windows)
01789         {
01790           dsp_windows_header_fragment.wincopy (output_file, constituent.variables, 3,
01791                                                &PACKAGE,
01792                                                &CONSTITUENT, 
01793                                                &CONSTITUENTSUFFIX);
01794         }
01795       else
01796         {
01797           dsp_application_header_fragment.wincopy (output_file, constituent.variables, 3,
01798                                                    &PACKAGE,
01799                                                    &CONSTITUENT, 
01800                                                    &CONSTITUENTSUFFIX);
01801         }
01802     }
01803 
01804   for (i = 0; i < sources.size (); i++)
01805     {
01806       file = sources[i];
01807 
01808       Context.set_full_name (full_name, file);
01809       if (full_name == "") continue;
01810 
01811       static CmtSystem::cmt_string_vector files;
01812 
01813       get_all_files (full_name, files);
01814 
01815       for (int j = 0; j < files.size (); j++)
01816         {
01817           const cmt_string& name = files[j];
01818 
01819           if (name != "") 
01820             {
01821               FULLNAME = name;
01822 
01823               if (output_file != NULL)
01824                 {
01825                   dsp_contents_fragment.wincopy (output_file, constituent.variables, 2, 
01826                                                  &PACKAGE, 
01827                                                  &FULLNAME);
01828                 }
01829               if (output_file_s != NULL)
01830                 {
01831                   dsp_contents_fragment.wincopy (output_file_s, constituent.variables, 2, 
01832                                                  &PACKAGE,
01833                                                  &FULLNAME);
01834                 }
01835             }
01836         }
01837 
01838       /*
01839         CmtSystem::get_suffix (full_name, suffix);
01840 
01841         if (file.find ('*') != cmt_string::npos)
01842         {
01843         static CmtSystem::cmt_string_vector files;
01844 
01845         CmtSystem::scan_dir (full_name, files);
01846 
01847         if (Cmt::get_debug ())
01848         {
01849         cout << "CMT> full_name=" << full_name <<
01850         " pwd=" << CmtSystem::pwd () << endl;
01851         cout << "CMT> files.size=" <<  files.size () << endl;
01852         }
01853 
01854         for (int j = 0; j < files.size (); j++)
01855         {
01856         const cmt_string& nnn = files[j];
01857         static cmt_string sss;
01858 
01859         CmtSystem::get_suffix (nnn, sss);
01860         if (sss == suffix)
01861         {
01862         FULLNAME = nnn;
01863         if (output_file != NULL)
01864         {
01865         dsp_contents_fragment.wincopy (output_file,
01866         constituent.variables, 1, &FULLNAME);
01867         }
01868         if (output_file_s != NULL)
01869         {
01870         dsp_contents_fragment.wincopy (output_file_s,
01871         constituent.variables, 1, &FULLNAME);
01872         }
01873         }
01874         }
01875         }
01876         else
01877         {
01878         FULLNAME = full_name;
01879         if (output_file != NULL)
01880         {
01881         dsp_contents_fragment.wincopy (output_file, constituent.variables, 1, &FULLNAME);
01882         }
01883         if (output_file_s != NULL)
01884         {
01885         dsp_contents_fragment.wincopy (output_file_s, constituent.variables, 1, &FULLNAME);
01886         }
01887         }
01888       */
01889     }
01890 
01891   if (output_file != NULL)
01892     {
01893       dsp_trailer_fragment.wincopy (output_file, constituent.variables, 3,
01894                                     &PACKAGE,
01895                                     &CONSTITUENT, 
01896                                     &CONSTITUENTSUFFIX);
01897       fclose (output_file);
01898       commit (output);
01899     }
01900 
01901   if (output_file_s != NULL)
01902     {
01903       dsp_trailer_fragment.wincopy (output_file_s, constituent.variables, 3,
01904                                     &PACKAGE,
01905                                     &CONSTITUENT, 
01906                                     &CONSTITUENTSUFFIX);
01907       fclose (output_file_s);
01908       commit (output_s);
01909     }
01910 
01911   return (0);
01912 }
01913 
01914 //--------------------------------------------------
01915 void Generator::build_make_setup (const cmt_string& package)
01916 {
01917   Context.reset ();
01918 
01919   PACKAGE = package;
01920 
01921   FILE* output_file;
01922 
01923   cmt_string file_name = "setup.";
01924 
01925   if (Cmt::build_nmake ())
01926     {
01927       file_name += "nmake";
01928     }
01929   else
01930     {
01931       file_name += "make";
01932     }
01933   
01934   cmt_string new_file_name = file_name;
01935   new_file_name += "new";
01936 
01937   output_file = fopen (new_file_name, "wb");
01938 
01939   if (output_file != NULL)
01940     {
01941       int number;
01942       const Use::UsePtrVector& uses = Use::uses ();
01943       const Constituent::ConstituentVector& constituents =
01944         Constituent::constituents ();
01945       cmt_string temp;
01946 
01947       make_setup_header_fragment.copy (output_file, 1, &PACKAGE);
01948 
01949       for (number = 0; number < uses.size (); number++)
01950         {
01951           const Use* use = uses[number];
01952 
01953           if (use->discarded) continue;
01954 
01955           if (use->real_path != "")
01956             {
01957               temp  = use->prefix;
01958               temp += "ROOT = ";
01959               temp += use->real_path;
01960               temp += SLASH;
01961               temp += use->package;
01962               temp += SLASH;
01963               temp += use->version;
01964 
01965               fprintf (output_file, "%s\n", temp.c_str());
01966             }
01967         }
01968 
01969       temp  = "use_requirements = ";
01970       temp += "requirements ";
01971 
01972       for (number = 0; number < uses.size (); number++)
01973         {
01974           const Use* use = uses[number];
01975 
01976           if (use->discarded) continue;
01977 
01978           if (use->real_path != "")
01979             {
01980               temp += "$(";
01981               temp += use->prefix;
01982               temp += "ROOT)";
01983               temp += CmtSystem::file_separator ();
01984               switch (use->style)
01985                 {
01986                 case cmt_style:
01987                   temp += "cmt";
01988                   break;
01989                 case mgr_style:
01990                   temp += "mgr";
01991                   break;
01992                 }
01993               temp += CmtSystem::file_separator ();
01994               temp += "requirements ";
01995             }
01996         }
01997 
01998       fprintf (output_file, "%s\n", temp.c_str());
01999 
02000       temp  = "constituents = $(constituents)";
02001       Symbol::expand (temp);
02002 
02003       fprintf (output_file, "%s\n", temp.c_str());
02004 
02005       make_setup_fragment.copy (output_file, 1, &PACKAGE);
02006 
02007       fclose (output_file);
02008 
02009       //--- Complete the operation --------------
02010 
02011       commit (new_file_name);
02012     }
02013 
02014   /*
02015     for option in $*
02016     do
02017     case ${option} in
02018     args-tag=*)
02019     tag=${option}
02020     tag=`echo "${tag}" | sed -e 's/args.tag=//'`
02021     ;;
02022     -tag=*)
02023     tag=args${option}
02024     tag=`echo "${tag}" | sed -e 's/args.tag=//'`
02025     ;;
02026     esac
02027     done
02028 
02029     if test "${tag}" = "" ; then
02030     tag=${CMTCONFIG}
02031     fi
02032 
02033     build_shell_setup_files ${tag}
02034 
02035     now=`date`
02036 
02037   */
02038 }
02039 
02040 //--------------------------------------------------
02041 void Generator::build_constituents_makefile (const cmt_string& package)
02042 {
02043   Context.reset ();
02044   cmt_string file_name = "constituents.";
02045 
02046   //--- Build the constituents fragment -----
02047 
02048   if (Cmt::build_nmake ())
02049     {
02050       file_name += "nmake";
02051     }
02052   else
02053     {
02054       file_name += "make";
02055     }
02056 
02057   cmt_string save_file_name = file_name;
02058   save_file_name += "sav";
02059 
02060   if (CmtSystem::test_file (file_name))
02061     {
02062       rename (file_name, save_file_name);
02063     }
02064 
02065   cmt_string new_file_name = file_name;
02066   new_file_name += "new";
02067 
02068   FILE* output_file = fopen (new_file_name, "wb");
02069   if (output_file != NULL)
02070     {
02071       int number;
02072       const Constituent::ConstituentVector&
02073         constituents = Constituent::constituents ();
02074 
02075       PACKAGE = package;
02076 
02077       constituents_header_fragment.copy (output_file, 1, &PACKAGE);
02078 
02079       GROUP = "all";
02080       group_fragment.copy (output_file, 1, &GROUP);
02081 
02082       const Group::GroupVector& groups = Group::groups ();
02083 
02084       for (number = 0; number < groups.size (); number++)
02085         {
02086           const Group& group = groups[number];
02087 
02088           GROUP = group.name ();
02089 
02090           group_fragment.copy (output_file, 1, &GROUP);
02091         }
02092       
02093       for (number = 0; number < constituents.size (); number++)
02094         {
02095           const Constituent& constituent = constituents[number];
02096 
02097           CONSTITUENT = constituent.name;
02098           CONSTITUENTSUFFIX = constituent.suffix;
02099 
02100           LINE = "";
02101 
02102           const CmtSystem::cmt_string_vector& sources = constituent.modules;
02103 
02104           constituent_fragment.copy (output_file, constituent.variables, 3, 
02105                                      &CONSTITUENT, &CONSTITUENTSUFFIX, &LINE);
02106 
02107           if (constituent.need_check)
02108             {
02109               check_application_header_fragment.copy (output_file, 
02110                                                       constituent.variables, 2,
02111                                                       &CONSTITUENT, &CONSTITUENTSUFFIX);
02112             }
02113         }
02114 
02115       constituents_trailer_fragment.copy (output_file, 0);
02116 
02117       fclose (output_file);
02118 
02119       commit (new_file_name);
02120     }
02121 }
02122 
02123 //--------------------------------------------------
02124 int Generator::build_constituent_makefile (const Constituent& constituent)
02125 {
02126   Context.reset ();
02127 
02128   const cmt_string& package = Cmt::get_current_package ();
02129 
02130   int i;
02131 
02132   PACKAGE = package;
02133   CONSTITUENT = constituent.name;
02134   CONSTITUENTSUFFIX = constituent.suffix;
02135 
02136   for (i = 0; i < constituent.includes.size (); i++)
02137     {
02138       const cmt_string& include = constituent.includes[i];
02139       Context.PACKINCLUDES += " -I" + include;
02140     }
02141 
02142   switch (constituent.type)
02143     {
02144     case Application:
02145       Context.is_library = false;
02146       Context.is_application = true;
02147       Context.is_document = false;
02148       TITLE = "Application";
02149       break;
02150     case Library:
02151       Context.is_library = true;
02152       Context.is_application = false;
02153       Context.is_document = false;
02154       TITLE = "Library";
02155       break;
02156     case Document:
02157       Context.is_library = false;
02158       Context.is_application = false;
02159       Context.is_document = true;
02160       Context.GENERATOR = constituent.generator;
02161       TITLE = "Document";
02162       break;
02163     }
02164 
02165   Context.PACKOS9 = constituent.need_OS9;
02166 
02167   cmt_string output = Context.cmtdir + CONSTITUENT + ".";
02168 
02169   if (Cmt::build_nmake ())
02170     {
02171       output += "nmake";
02172     }
02173   else
02174     {
02175       output += "make";
02176     }
02177   
02178   output += "new";
02179 
02180 
02181   Context.output_file = fopen (output.c_str (), "wb");
02182   if (Context.output_file != NULL)
02183     {
02184       if (Context.is_library)
02185         {
02186           Context.build_library_makefile (package, constituent);
02187         }
02188       else if (Context.is_application)
02189         {
02190           Context.build_application_makefile (package, constituent);
02191         }
02192       else if (Context.is_document)
02193         {
02194           Context.build_document_makefile (package, constituent);
02195         }
02196 
02197       fclose (Context.output_file);
02198 
02199       //--- Complete the operation --------------
02200 
02201       commit (output);
02202     }
02203 
02204   return (0);
02205 }
02206 
02207 //--------------------------------------------------
02208 void Generator::build_constituent_makefile (const cmt_string& name)
02209 {
02210   const Constituent* constituent = Constituent::find (name);
02211   if (constituent != 0) build_constituent_makefile (*constituent);
02212 }
02213 
02214 //--------------------------------------------------
02215 void Generator::build_default_makefile ()
02216 {
02217   cmt_string makefile;
02218 
02219   //--- Build a simple Makefile if none is installed
02220 
02221 #ifndef WIN32
02222 
02223   bool need_makefile = false;
02224 
02225   makefile = Context.cmtdir + "Makefile";
02226 
02227   if (!CmtSystem::test_file (makefile))
02228     {
02229       need_makefile = true;
02230     }
02231   else
02232     {
02233       static cmt_string s;
02234 
02235       s.read (makefile);
02236       if ((s.find ("METHODSROOT") != cmt_string::npos) ||
02237           (s.find ("$(CMTROOT)/src/constituents.make") == cmt_string::npos))
02238         {
02239           static cmt_string backup = makefile;
02240           backup += "_backup";
02241 
02242           makefile += ".cmt";
02243 
02244           if (!CmtSystem::test_file (makefile))
02245             {
02246               FILE* file = fopen (backup.c_str (), "wb");
02247               if (file != NULL)
02248                 {
02249                   cout << "# " << endl;
02250                   cout << "#CMT> Warning !!! " << endl;
02251                   cout << "# A Makefile already exists "
02252                     "but it does not provides " << endl;
02253                   cout << "# the recommended features "
02254                     "for a full benefit of CMT" << endl;
02255                   cout << "# " << endl;
02256                   cout << "# CMT is now building "
02257                     "a new 'Makefile.cmt' which you can use" << endl;
02258                   cout << "# to upgrade your current one." << endl;
02259                   cout << "# " << endl;
02260 
02261                   s.write (file);
02262                   fclose (file);
02263 
02264                   need_makefile = true;
02265                 }
02266             }
02267         }
02268     }
02269 
02270   if (need_makefile)
02271     {
02272       FILE* file = fopen (makefile.c_str (), "wb");
02273       if (file != NULL)
02274         {
02275           fprintf (file, "include $(CMTROOT)/src/Makefile.header\n");
02276           fprintf (file, "\n");
02277           fprintf (file, "include $(CMTROOT)/src/constituents.make\n");
02278           fprintf (file, "\n");
02279           fclose (file);
02280         }
02281     }
02282 
02283 #endif
02284 
02285 #ifdef WIN32
02286 
02287   makefile = Context.cmtdir + "NMake";
02288 
02289   if (!CmtSystem::test_file (makefile))
02290     {
02291       FILE* file = fopen (makefile.c_str (), "wb");
02292       if (file != NULL)
02293         {
02294           fprintf (file, "!include $(CMTROOT)\\src\\NMakefile.header\n");
02295           fprintf (file, "\n");
02296           fprintf (file, "!include $(CMTROOT)\\src\\constituents.nmake\n");
02297           fprintf (file, "\n");
02298           fclose (file);
02299         }
02300     }
02301 
02302 #endif
02303 
02304 }
02305 
02306 //--------------------------------------------------
02307 cmt_string Generator::build_dependencies (const cmt_string& file_name)
02308 {
02309   static cmt_string full_name;
02310   static cmt_string suffix;
02311   static cmt_string name;
02312   static cmt_string line;
02313 
02314   full_name = "";
02315   line = "";
02316 
02317   if (!CmtSystem::absolute_path (file_name))
02318     {
02319       full_name = Context.srcdir;
02320     }
02321 
02322   full_name += file_name;
02323 
02324   CmtSystem::get_dot_suffix (full_name, suffix);
02325   CmtSystem::basename (full_name, suffix, name);
02326   CmtSystem::get_suffix (full_name, suffix);
02327 
02328   if (name == "requirements") return (line);
02329 
02330   const CmtSystem::cmt_string_vector& deps = Context.deps_builder.run (full_name);
02331 
02332   line  = name;
02333   line += "_";
02334   line += suffix;
02335   line += "_dependencies = ";
02336   line += full_name;
02337   line += " ";
02338 
02339   for (int j = 0; j < deps.size (); j++)
02340     {
02341       line += deps[j];
02342       line += " ";
02343     }
02344 
02345   filter_paths (line);
02346 
02347   return (line);
02348 }
02349 
02350 //--------------------------------------------------
02351 //  o text contains lines with a pattern like :
02352 //      key = xxxxx
02353 //
02354 //  o line follows the same pattern
02355 //
02356 //   This function appends <line> to <text> only if the key found in
02357 //  <line> is not found in <text>
02358 //--------------------------------------------------
02359 static void add_line_to_text (const cmt_string& line, cmt_string& text)
02360 {
02361   static const cmt_string empty;
02362 
02363   int pos = line.find (" = ");
02364   if (pos != cmt_string::npos)
02365     {
02366       static cmt_string key;
02367       line.substr (0, pos + 3, key);
02368       pos = text.find (key);
02369       if (pos != cmt_string::npos)
02370         {
02371           // The key in line exists in text.
02372           // Now check if the key is exactly the same.
02373 
02374           if ((pos == 0) || (text[pos -1] == '\n'))
02375             {
02376               // The key is either in the first line or
02377               // exactly matches '^key = ...'
02378 
02379               int nl = text.find (pos, "\n");
02380               if (nl != cmt_string::npos)
02381                 {
02382                   static cmt_string old;
02383                   text.substr (pos, nl - pos + 1, old);
02384                   text.replace (old, empty);
02385                 }
02386               else
02387                 {
02388                   text.erase (pos);
02389                 }
02390             }
02391         }
02392     }
02393   if (line != "")
02394     {
02395       text += line;
02396       text += "\n";
02397     }
02398 }
02399 
02400 //--------------------------------------------------
02401 class DependencyFilter : public Awk
02402 {
02403 public:
02404   DependencyFilter ()
02405       {
02406       }
02407 
02408   void begin ()
02409       {
02410         m_sources = "";
02411       }
02412 
02413   void filter (const cmt_string& line)
02414       {
02415         int pos = line.find ("_dependencies = ");
02416         if (pos == cmt_string::npos) return;
02417 
02418         cmt_string s = line;
02419         s.erase (pos);
02420 
02421         m_sources += " ";
02422         m_sources += s;
02423         m_sources += " ";
02424 
02425           //pos = s.find_last_of ("_");
02426           //if (pos != cmt_string::npos) s[pos] = "."
02427       }
02428 
02429   void add_source (const cmt_string& file_name)
02430       {
02431         static cmt_string suffix;
02432         static cmt_string name;
02433 
02434         CmtSystem::get_dot_suffix (file_name, suffix);
02435         CmtSystem::basename (file_name, suffix, name);
02436         CmtSystem::get_suffix (file_name, suffix);
02437 
02438         cmt_string s = " ";
02439         s += name;
02440         s += "_";
02441         s += suffix;
02442         s += " ";
02443 
02444         if (m_sources.find (s) == cmt_string::npos)
02445           {
02446             m_sources += s;
02447           }        
02448       }
02449 
02450   bool has_source (const cmt_string& file_name) const
02451       {
02452         static cmt_string suffix;
02453         static cmt_string name;
02454 
02455         CmtSystem::get_dot_suffix (file_name, suffix);
02456         CmtSystem::basename (file_name, suffix, name);
02457         CmtSystem::get_suffix (file_name, suffix);
02458 
02459         cmt_string s = " ";
02460         s += name;
02461         s += "_";
02462         s += suffix;
02463         s += " ";
02464 
02465         if (m_sources.find (s) == cmt_string::npos)
02466           {
02467             return (false);
02468           }
02469         else
02470           {
02471             return (true);
02472           }
02473       }
02474 
02475   cmt_string& get_sources ()
02476       {
02477         return (m_sources);
02478       }
02479 
02480 private:
02481   cmt_string m_sources;
02482 };
02483 
02484 //--------------------------------------------------
02485 void Generator::build_dependencies (const cmt_string& name,
02486                                     int argc, char* argv[])
02487 {
02488   Context.reset ();
02489   Context.prepare_use_context ();
02490 
02491   const Constituent* constituent_ptr = Constituent::find (name);
02492   if (constituent_ptr == 0)
02493     {
02494       // Error : wrong constituent name...
02495       return;
02496     }
02497 
02498   const Constituent& constituent = *constituent_ptr;
02499 
02500   cmt_string file_name;
02501   cmt_string full_name;
02502   cmt_string compressed_name;
02503   cmt_string suffix;
02504   cmt_string dependencies;
02505 
02506   static cmt_string output_name;
02507 
02508   cmt_string branch = CmtSystem::current_branch ();
02509 
02510   if ((branch == "mgr") || (branch == "cmt"))
02511     {
02512       Use& current_use = Use::current ();
02513 
02514       if (current_use.package == "CMT")
02515         {
02516           output_name = "../";
02517           output_name += CmtSystem::getenv ("CMTBIN");
02518           output_name += CmtSystem::file_separator ();
02519         }
02520       else
02521         {
02522           output_name = "${bin}";
02523         }
02524 
02525       Symbol::expand (output_name);
02526 
02527       //cerr << "output_name=" << output_name << endl;
02528       //cerr << "current_tag=" << Cmt::current_tag << endl;
02529     }
02530 
02531   output_name += name;
02532   output_name += "_";
02533   output_name += "dependencies.";
02534   if (Cmt::build_nmake ())
02535     {
02536       output_name += "nmake";
02537     }
02538   else
02539     {
02540       output_name += "make";
02541     }
02542 
02543   static DependencyFilter filter;
02544 
02545   dependencies.read (output_name);
02546 
02547   filter.run (dependencies);
02548 
02549   //
02550   // Scan the sources.
02551   //
02552 
02553     //
02554     //  We have to rebuild the dependencies for :
02555     //
02556     //   o all sources if the parameter -all_sources has been received
02557     //   o otherwise,
02558     //      + all source names provided in the argument list (if any)
02559     //      + all source names missing from the existing dependency file (if any)
02560     //
02561 
02562   const CmtSystem::cmt_string_vector& sources = constituent.modules;
02563   bool all_sources = false;
02564 
02565   int source_number = argc;
02566   int i;
02567 
02568   for (i = argc-1; i >= 0; i--)
02569     {
02570       file_name = argv[i];
02571 
02572         // Get rid of files that may come from the makefile fragment
02573       if (file_name.find ("requirements") != cmt_string::npos) source_number--;
02574       else if (file_name.find (".make") != cmt_string::npos) source_number--;
02575       else if (file_name == "-all_sources") 
02576         {
02577           source_number = sources.size ();
02578           all_sources = true;
02579         }
02580     }
02581 
02582 
02583   if (all_sources)
02584     {
02585       for (i = 0; i < sources.size (); i++)
02586         {
02587           file_name = sources[i];
02588           
02589           Context.set_full_name (full_name, file_name);
02590           if (full_name == "") continue;
02591 
02592           CmtSystem::compress_path (full_name, compressed_name);
02593           full_name = compressed_name;
02594           
02595           static CmtSystem::cmt_string_vector files;
02596 
02597           get_all_files (full_name, files);
02598 
02599           for (int j = 0; j < files.size (); j++)
02600             {
02601               const cmt_string& name = files[j];
02602               
02603               if (name != "") 
02604                 {
02605                   const cmt_string& line = build_dependencies (name);
02606                   
02607                     //cout << ">>> name1=" << name << endl;
02608                   
02609                   add_line_to_text (line, dependencies);
02610                 }
02611             }
02612         }
02613     }
02614   else
02615     {
02616       for (i = 0; i < source_number; i++)
02617         {
02618           file_name = argv[i];
02619           
02620           Context.set_full_name (full_name, file_name);
02621           if (full_name == "") continue;
02622 
02623           CmtSystem::compress_path (full_name, compressed_name);
02624           full_name = compressed_name;
02625           
02626           const cmt_string& line = build_dependencies (full_name);
02627                   
02628             //cout << ">>> name2=" << full_name << endl;
02629                   
02630           add_line_to_text (line, dependencies);
02631 
02632             //cout << ">>from deps : " << filter.get_sources () << endl;
02633           filter.add_source (full_name);
02634 
02635         }
02636 
02637         //cout << ">>from deps : " << filter.get_sources () << endl;
02638 
02639         // Now : are there still any missing source file in dependencies??
02640 
02641       for (i = 0; i < sources.size (); i++)
02642         {
02643           file_name = sources[i];
02644           
02645           Context.set_full_name (full_name, file_name);
02646           if (full_name == "") continue;
02647           
02648           CmtSystem::compress_path (full_name, compressed_name);
02649           full_name = compressed_name;
02650           
02651           static CmtSystem::cmt_string_vector files;
02652           
02653           get_all_files (full_name, files);
02654 
02655           for (int j = 0; j < files.size (); j++)
02656             {
02657               const cmt_string& name = files[j];
02658               
02659               if (name != "") 
02660                 {
02661                   if (!filter.has_source (name))
02662                     {
02663                       const cmt_string& line = build_dependencies (name);
02664                   
02665                         //cout << ">>> name3=" << name << endl;
02666                   
02667                       add_line_to_text (line, dependencies);
02668                     }
02669                 }
02670             }
02671         }
02672     }
02673 
02674   FILE* f = fopen (output_name.c_str (), "wb");
02675 
02676   if (f == 0)
02677     {
02678       cerr << "Cannot open " << output_name << " for write" << endl;
02679     }
02680   else
02681     {
02682       dependencies.write (f);
02683       fclose (f);
02684     }
02685 }
02686 
02687 //--------------------------------------------------
02688 class Prototyper : public FAwk
02689 {
02690 public:
02691   Prototyper (bool static_functions = false) :
02692     m_static_functions(static_functions)
02693   {
02694     if (m_static_functions)
02695       {
02696         m_suffix = "_static.phnew";
02697         m_define_suffix = "_static_ph";
02698       }
02699     else
02700       {
02701         m_suffix = ".phnew";
02702         m_define_suffix = "_ph";
02703       }
02704   }
02705 
02706   void begin ()
02707   {
02708     m_running = false;
02709 
02710     static cmt_string suffix;
02711     static cmt_string name;
02712 
02713     CmtSystem::get_dot_suffix (m_file_name, suffix);
02714     CmtSystem::basename (m_file_name, suffix, name);
02715 
02716     m_out_file_name  = "";
02717 
02718     if (m_dir_name != "")
02719       {
02720         m_out_file_name  = m_dir_name;
02721         m_out_file_name += CmtSystem::file_separator ();
02722       }
02723 
02724     m_out_file_name += name;
02725     m_out_file_name += m_suffix;
02726 
02727     CmtSystem::basename (m_file_name, suffix, m_file_name);
02728 
02729     m_output = fopen (m_out_file_name.c_str (), "wb");
02730 
02731     if (m_output != 0)
02732       {
02733         fprintf (m_output, "#ifndef __%s%s__\n", m_file_name.c_str (),
02734                  m_define_suffix.c_str ());
02735         fprintf (m_output, "#define __%s%s__\n", m_file_name.c_str (),
02736                  m_define_suffix.c_str ());
02737 
02738         fprintf (m_output, "\n");
02739         fprintf (m_output, "#ifdef __cplusplus\n");
02740         fprintf (m_output, "extern \"C\" {\n");
02741         fprintf (m_output, "#endif\n");
02742         fprintf (m_output, "\n");
02743       }
02744     else
02745       {
02746         stop ();
02747       }
02748   }
02749 
02750   void filter (const cmt_string& line)
02751   {
02752     char c = line[0];
02753 
02754     if (!m_running)
02755       {
02756         if ((c == ' ') ||
02757             (c == '/') ||
02758             (c == '|') ||
02759             (c == '\t') ||
02760             (c == '#')) return;
02761         if (line.find ('(') == cmt_string::npos)
02762           {
02763             m_prev_line = line;
02764             return;
02765           }
02766 
02767         m_running = true;
02768         m_full_line = line;
02769         m_full_line.replace ("(", " (");
02770 
02771         static CmtSystem::cmt_string_vector words;
02772 
02773         CmtSystem::split (m_full_line, " \t", words);
02774 
02775         const cmt_string& second = words[1];
02776         if (second[0] == '(')
02777           {
02778             m_full_line = m_prev_line;
02779             m_full_line += " ";
02780             m_full_line += line;
02781 
02782             m_prev_line = "";
02783           }
02784       }
02785     else
02786       {
02787         m_full_line += line;
02788       }
02789     if (line.find (')') == cmt_string::npos) return;
02790     m_running = false;
02791 
02792     if (m_full_line.find (';') != cmt_string::npos) return;
02793     if (m_full_line.find ("::") != cmt_string::npos) return;
02794     if (m_full_line.find ('<') != cmt_string::npos) return;
02795     if (m_full_line.find ('>') != cmt_string::npos) return;
02796     if (m_full_line.find ('{') != cmt_string::npos) return;
02797     if (m_full_line.find ('}') != cmt_string::npos) return;
02798     if (m_full_line.find ("typedef") != cmt_string::npos) return;
02799     if (m_full_line.find ("yy") != cmt_string::npos) return;
02800     if (m_full_line.find ("YY") != cmt_string::npos) return;
02801     if (m_static_functions)
02802       {
02803         if (m_full_line.find ("static") == cmt_string::npos) return;
02804       }
02805     else
02806       {
02807         if (m_full_line.find ("static") != cmt_string::npos) return;
02808       }
02809 
02810     m_full_line += ";";
02811 
02812     if (m_output != 0)
02813       {
02814         fprintf (m_output, "%s\n", m_full_line.c_str ());
02815       }
02816   }
02817 
02818   void end ()
02819   {
02820     if (m_output != 0)
02821       {
02822         fprintf (m_output, "\n");
02823         fprintf (m_output, "#ifdef __cplusplus\n");
02824         fprintf (m_output, "}\n");
02825         fprintf (m_output, "#endif\n");
02826         fprintf (m_output, "\n");
02827         fprintf (m_output, "#endif\n");
02828         fprintf (m_output, "\n");
02829 
02830         fclose (m_output);
02831       }
02832 
02833     Generator::check (m_out_file_name);
02834   }
02835 
02836 private:
02837   bool m_running;
02838   cmt_string m_out_file_name;
02839   FILE* m_output;
02840   bool m_static_functions;
02841   cmt_string m_full_line;
02842   cmt_string m_prev_line;
02843   cmt_string m_suffix;
02844   cmt_string m_define_suffix;
02845 };
02846 //--------------------------------------------------
02847 
02848 //--------------------------------------------------
02849 void Generator::build_prototype (const cmt_string& file_name)
02850 {
02851   Prototyper prototyper;
02852 
02853   prototyper.run (file_name);
02854   /*
02855     static cmt_string pp;
02856     pp  = incdir;
02857     pp += name;
02858     pp += ".pp";
02859   */
02860 }
02861 
02862 //--------------------------------------------------
02863 void Generator::build_readme (const CmtSystem::cmt_string_vector& arguments)
02864 {
02865   Context.reset ();
02866 
02867   PACKAGE = Cmt::get_current_package ();
02868   VERSION = Cmt::get_current_version ();
02869   DATE = CmtSystem::now ();
02870   USER = CmtSystem::user ();
02871 
02872   cmt_string url;
02873   cmt_string doc;
02874 
02875   for (int i = 0; i < arguments.size (); i++)
02876     {
02877       cmt_string arg = arguments[i];
02878 
02879       if (arg.substr (0, 5) == "-url=")
02880         {
02881           arg.substr (5, url);
02882         }
02883       else if (arg.substr (0, 5) == "-doc=")
02884         {
02885           arg.substr (5, doc);
02886         }
02887     }
02888 
02889   cmt_string output = Context.cmtdir + "README.html";
02890 
02891   Context.output_file = fopen (output.c_str (), "wb");
02892   if (Context.output_file != NULL)
02893     {
02894       readme_header_fragment.copy (Context.output_file, 2, &PACKAGE, &VERSION);
02895 
02896       if (doc != "")
02897         {
02898           DOCPATH = doc;
02899           readme_doc_fragment.copy (Context.output_file, 3, &PACKAGE, &VERSION, &DOCPATH);
02900         }
02901 
02902       readme_fragment.copy (Context.output_file, 2, &PACKAGE, &VERSION);
02903 
02904       int number;
02905       const Use::UsePtrVector& uses = Use::uses ();
02906 
02907       for (number = 0; number < uses.size (); number++)
02908         {
02909           const Use* use = uses[number];
02910           if (use->discarded) continue;
02911           if ((use != 0) && (use->package != "CMT"))
02912             {
02913               cmt_string selected_path;
02914 
02915               if (url == "")
02916                 {
02917                   selected_path = use->real_path;
02918 
02919                   if (use->specified_path != "")
02920                     {
02921                       int pos = selected_path.find_last_of (use->specified_path);
02922                       if (pos != cmt_string::npos)
02923                         {
02924                           selected_path.erase (pos);
02925                         }
02926                     }
02927                 }
02928               else
02929                 {
02930                   selected_path = url;
02931 
02932                   if (use->specified_path != "")
02933                     {
02934                       selected_path += CmtSystem::file_separator ();
02935                     }
02936                 }
02937 
02938               PACKAGEPATH = selected_path;
02939               PACKAGEPREFIX = use->specified_path;
02940               PACKAGE = use->package;
02941               VERSION = use->version;
02942               MGRSTYLE = (use->style == mgr_style) ? "mgr" : "cmt";
02943               readme_use_fragment.copy (Context.output_file, 5,
02944                                         &PACKAGEPATH,
02945                                         &PACKAGEPREFIX,
02946                                         &PACKAGE,
02947                                         &VERSION,
02948                                         &MGRSTYLE);
02949             }
02950         }
02951       PACKAGE = Cmt::get_current_package ();
02952       VERSION = Cmt::get_current_version ();
02953       readme_trailer_fragment.copy (Context.output_file, 4, 
02954                                     &PACKAGE, 
02955                                     &VERSION, 
02956                                     &DATE, 
02957                                     &USER);
02958     }
02959 }
02960 
02961 class WinDefAwk : public PAwk
02962 {
02963 public :
02964    WinDefAwk (const cmt_string& library_name)
02965     {
02966       m_name = library_name;
02967     }
02968 
02969   void begin ()
02970     {
02971       cout << "LIBRARY " << m_name << endl;
02972       cout << "EXPORTS" << endl;
02973     }
02974 
02975   void filter (const cmt_string& line)
02976     {
02977       if (line.find ("External") == cmt_string::npos) return;
02978       if (line.find ("??_") != cmt_string::npos) return;
02979 
02980       CmtSystem::cmt_string_vector words;
02981       CmtSystem::split (line, " \t", words);
02982       if (words.size () >= 8)
02983         {
02984           int pos = 7;
02985 
02986           cmt_string& fifth_word = words[4];
02987           if (fifth_word == "()") pos = 7;
02988           else if (fifth_word == "External") pos = 6;
02989           else return;
02990 
02991           cmt_string& symbol = words[pos];
02992           if (symbol[0] == '_') symbol.erase (0, 1);
02993           symbol.replace_all ("\r", "");
02994           symbol.replace_all ("\n", "");
02995           cout << " " << symbol << (pos == 6 ? "\tDATA" : " ") << endl;
02996         }
02997     }
02998 
02999   void end ()
03000     {
03001     }
03002 
03003 private:
03004   cmt_string m_name;
03005 };
03006 
03007 //--------------------------------------------------
03008 void Generator::build_windefs (const cmt_string& library_name)
03009 {
03010         cmt_string bin;
03011         cmt_string name;
03012         cmt_string suffix;
03013 
03014         CmtSystem::dirname (library_name, bin);
03015         CmtSystem::get_dot_suffix (library_name, suffix);
03016         CmtSystem::basename (library_name, suffix, name);
03017 
03018         if (!CmtSystem::cd (bin)) return;
03019         
03020         cmt_string text;
03021         cmt_string command;
03022         
03023         command = "dumpbin /symbols ";
03024         command += library_name;
03025         
03026         WinDefAwk filter (name);
03027         
03028         filter.run (command, "SECT");
03029 }
03030 
03031 //--------------------------------------------------
03032 void Packager::begin ()
03033 {
03034   m_package_name = "";
03035 }
03036 
03037 void Packager::filter (const cmt_string& line)
03038 {
03039   CmtSystem::cmt_string_vector words;
03040 
03041   CmtSystem::split (line, " ", words);
03042   if (words.size () > 1)
03043     {
03044       cmt_string& w = words[0];
03045 
03046       if (w == "package")
03047         {
03048           m_package_name = words[1];
03049 
03050           int pos = m_package_name.find (";");
03051           if (pos != cmt_string::npos) m_package_name.erase (pos);
03052           m_package_name.replace_all (".", CmtSystem::file_separator ());
03053         }
03054     }
03055 }
03056 
03057 cmt_string& Packager::package_name ()
03058 {
03059   return (m_package_name);
03060 }
03061 

Generated at Thu Apr 11 16:49:40 2002 for CMT by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000