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