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

cmt_generators.cxx

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

Generated on Mon May 2 10:25:04 2005 for CMT by 1.3.5