//----------------------------------------------------------- // Copyright Christian Arnault LAL-Orsay CNRS // arnault@lal.in2p3.fr // See the complete license in cmt_license.txt "http://www.cecill.info". //----------------------------------------------------------- #include "cmt_generators.h" #include "cmt_awk.h" #include "cmt_use.h" #include "cmt_symbol.h" #include "cmt_log.h" //-------------------------------------------------- AnyDocumentGenerator::AnyDocumentGenerator () { m_TITLE.set ("TITLE"); make_header_fragment.set ("make_header"); cleanup_header_fragment.set ("cleanup_header"); cleanup_fragment.set ("cleanup"); dependencies_fragment.set ("dependencies"); dependencies_and_triggers_fragment.set ("dependencies_and_triggers"); } void AnyDocumentGenerator::reset () { CmtGenerator::reset (); m_TITLE = ""; make_header_fragment.reset (); cleanup_header_fragment.reset (); cleanup_fragment.reset (); dependencies_fragment.reset (); dependencies_and_triggers_fragment.reset (); } //-------------------------------------------------- LibraryGenerator::LibraryGenerator () { library_header_fragment.set ("library_header"); application_header_fragment.set ("application_header"); java_header_fragment.set ("java_header"); jar_header_fragment.set ("jar_header"); protos_header_fragment.set ("protos_header"); library_fragment.set ("library"); library_no_share_fragment.set ("library_no_share"); application_fragment.set ("application"); jar_fragment.set ("jar"); java_fragment.set ("java"); java_copy_fragment.set ("java_copy"); cleanup_library_fragment.set ("cleanup_library"); cleanup_application_fragment.set ("cleanup_application"); cleanup_java_fragment.set ("cleanup_java"); cleanup_objects_fragment.set ("cleanup_objects"); buildproto_fragment.set ("buildproto"); check_application_fragment.set ("check_application"); check_java_fragment.set ("check_java"); } //-------------------------------------------------- void LibraryGenerator::reset () { AnyDocumentGenerator::reset (); library_header_fragment.reset (); application_header_fragment.reset (); java_header_fragment.reset (); jar_header_fragment.reset (); protos_header_fragment.reset (); library_fragment.reset (); library_no_share_fragment.reset (); jar_fragment.reset (); application_fragment.reset (); java_fragment.reset (); java_copy_fragment.reset (); cleanup_library_fragment.reset (); cleanup_application_fragment.reset (); cleanup_java_fragment.reset (); cleanup_objects_fragment.reset (); buildproto_fragment.reset (); check_application_fragment.reset (); check_java_fragment.reset (); } //-------------------------------------------------- bool LibraryGenerator::analyze_file (const Constituent& constituent, const cmt_string& file) { static cmt_string suffix; static cmt_string name; static cmt_string obj; bool file_not_found = false; bool can_build = true; obj = file; if (Cmt::get_debug ()) { cout << "CmtGenerator::analyze_file> constituent=" << constituent.name << " file=" << file << endl; } if (!CmtSystem::test_file (file) && !CmtSystem::test_directory (file)) { file_not_found = true; cerr << "#CMT> Warning: Source file " << file << " not found" << endl; } CmtSystem::get_suffix (file, suffix); CmtSystem::basename (file, suffix, name); Language& language = Language::find_with_suffix (suffix); if (m_LINKMACRO == "") { m_LINKMACRO = language.linker; } if (language == "java") { static Packager packager; obj = "$(javabin)"; obj += m_CONSTITUENT; obj += CmtSystem::file_separator (); cmt_regexp exp ("^package[ \t][ \t]*[a-zA-Z0-9_.][a-zA-Z0-9_.][ \t]*;"); packager.run (file, exp); if (packager.package_name () != "") { obj += packager.package_name (); obj += CmtSystem::file_separator (); } obj += name; obj += ".class"; } else if (language != Language::null ()) { obj = "$(bin)"; if (Cmt::build_nmake ()) obj += m_CONSTITUENT; if (Cmt::build_nmake ()) obj += CmtSystem::file_separator (); obj += name; obj += language.output_suffix; obj += constituent.suffix; if (Cmt::build_nmake ()) obj += ".obj"; else obj += ".o"; for (int i = 0; i < language.extra_output_suffixes.size (); i++) { cmt_string& extra_suffix = language.extra_output_suffixes[i]; obj += " $(bin)"; obj += name; obj += extra_suffix; obj += language.output_suffix; obj += constituent.suffix; if (Cmt::build_nmake ()) obj += ".obj"; else obj += ".o"; } } else { //cout << "#CMT> analyze_file file=" << file << " no language" << endl; if (m_LINKMACRO == "java") { obj = "$(javabin)"; obj += m_CONSTITUENT; obj += CmtSystem::file_separator (); obj += file; obj.replace ("../src/", ""); obj.replace ("..\\src\\", ""); } else if (file_not_found) { can_build = false; obj = ""; cerr << "#CMT> Warning: Source file " << name << " cannot be rebuilt" << endl; } else { obj = ""; } } if (Cmt::get_debug ()) { cout << "CmtGenerator::analyze_file> constituent=" << constituent.name << " obj=" << obj << endl; } if (can_build) { SourceFile& source = m_source_files.add (); source.set (file, language, obj); return (true); } else { return (false); } } //-------------------------------------------------- void LibraryGenerator::java_file_action (SourceFile& file, const Constituent& constituent) { static cmt_string suffix; m_FULLNAME = file.name (); m_OUTPUTNAME = file.output (); CmtSystem::get_dot_suffix (m_FULLNAME, suffix); CmtSystem::basename (m_FULLNAME, suffix, m_NAME.value); CmtSystem::basename (m_FULLNAME, m_FILENAME.value); if (CmtSystem::test_file (m_FULLNAME)) { java_fragment.copy (m_output_file, constituent.variables, 5, &m_NAME, &m_FULLNAME, &m_OUTPUTNAME, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } else { cerr << "#CMT> Warning: file " << m_FULLNAME << " not found" << endl; } } //-------------------------------------------------- void LibraryGenerator::proto_file_action (const cmt_string& file, const Constituent& constituent) { static cmt_string suffix; CmtSystem::dirname (file, m_FILEPATH.value); if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator (); filter_path (m_FILEPATH.value); CmtSystem::basename (file, m_FILENAME.value); CmtSystem::get_dot_suffix (m_FILENAME, suffix); CmtSystem::basename (m_FILENAME, suffix, m_NAME.value); buildproto_fragment.copy (m_output_file, constituent.variables, 3, &m_NAME, &m_FILEPATH, &m_FILENAME); } //-------------------------------------------------- void LibraryGenerator::prepare_proto_file (const cmt_string& file) { static cmt_string name; static cmt_string pp; CmtSystem::name (file, name); if (CmtSystem::test_file (file)) { pp = incdir; pp += name; pp += ".pp"; if (!CmtSystem::test_file (pp)) { //Generator::build_prototype (file); } } protos += " "; protos += inc; protos += name; protos += ".ph"; protonames += " "; protonames += name; protonames += ".ph"; m_PROTOSTAMPS += " "; m_PROTOSTAMPS += inc; m_PROTOSTAMPS += name; m_PROTOSTAMPS += ".pp"; } //-------------------------------------------------- void LibraryGenerator::module_file_action (SourceFile& file, const Constituent& constituent) { cmt_string name = file.name (); Language& language = file.language (); static cmt_string suffix; static cmt_string prefix; static cmt_string preproc; m_FULLNAME = name; CmtSystem::get_dot_suffix (name, suffix); CmtSystem::basename (name, suffix, m_NAME.value); CmtSystem::dirname (name, prefix); CmtSystem::basename (name, m_FILENAME.value); FragmentHandle* fragment; if (language != Language::null ()) { preproc = language.preprocessor_command; fragment = (is_library) ? &(language.library) : &(language.application); } else { // // What happens when the language is not known??? // // preproc = "-I"; fragment = 0; } if ((prefix == "../src") || (prefix == "..\\src")) { m_ADDINCLUDE = ""; } else if (prefix != "") { m_ADDINCLUDE = preproc; m_ADDINCLUDE += prefix; } m_FILEPATH = prefix; if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator (); filter_path (m_FILEPATH.value); m_LINE = m_FULLNAME.value; m_LINE += " "; filter_path (m_FULLNAME.value); filter_path (m_LINE.value); CmtSystem::get_suffix (name, m_FILESUFFIX.value); if (fragment != 0) { fragment->copy (m_output_file, constituent.variables, 10, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_FILENAME, &m_NAME, &m_LINE, &m_ADDINCLUDE, &m_FULLNAME, &m_FILEPATH, &m_FILESUFFIX, &m_PACKAGE); } else if (file.output () != "") { m_OUTPUTNAME = file.output (); CmtSystem::dirname (m_OUTPUTNAME.value, m_FILEPATH.value); java_copy_fragment.copy (m_output_file, constituent.variables, 11, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_FILENAME, &m_NAME, &m_LINE, &m_ADDINCLUDE, &m_FULLNAME, &m_FILEPATH, &m_FILESUFFIX, &m_PACKAGE, &m_OUTPUTNAME); } if (m_PACKOS9) { os9sources += m_LINE; os9sources += " "; } } //-------------------------------------------------- void LibraryGenerator::build (const cmt_string& package, const Constituent& constituent) { static cmt_string lib; static cmt_string allsources; static cmt_string file; static cmt_string full_name; static cmt_string compressed_name; static cmt_string suffix; int i; bool need_prototypes; reset (); if (!prepare_output (package, constituent)) return; switch (constituent.type) { case Application: is_library = false; is_application = true; m_TITLE = "Application"; break; case Library: is_library = true; is_application = false; m_TITLE = "Library"; break; } m_source_files.clear (); need_prototypes = constituent.need_prototypes; cout << m_TITLE << " " << m_CONSTITUENT << endl; lib = "$("; lib += m_CONSTITUENT; lib += "lib)"; // // Prepare the include paths // const CmtSystem::cmt_string_vector& includes = constituent.includes; for (i = 0; i < includes.size (); i++) { const cmt_string& subdir = includes[i]; m_PACKINCLUDES += " -I"; m_PACKINCLUDES += subdir; } // // Scan the sources. // const CmtSystem::cmt_string_vector& sources = constituent.modules; const cmt_vector& excludes = constituent.exclude_exprs; const cmt_vector& selects = constituent.select_exprs; m_LINE = ""; for (i = 0; i < sources.size (); i++) { file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; static CmtSystem::cmt_string_vector files; int count = get_all_files (full_name, excludes, selects, files); filter_path (full_name); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { if (!analyze_file (constituent, name)) { count = 0; break; } } } if (count > 0) { m_LINE += full_name; m_LINE += " "; } } fill_outputs (); prepare_use_context (); m_DATE = CmtSystem::now (); m_USER = CmtSystem::user (); m_PACKAGE = package; if (constituent.has_target_tag) { m_HASTARGETTAG = "has_target_tag"; } else { m_HASTARGETTAG = "has_no_target_tag"; } make_header_fragment.copy (m_output_file, constituent.variables, 7, &m_TITLE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_USER, &m_DATE, &m_PACKAGE, &m_HASTARGETTAG); if (need_prototypes) { need_prototypes = false; for (i = 0; i < m_source_files.size (); i++) { const SourceFile& file = m_source_files[i]; Language& language = file.language (); if (language.prototypes) { need_prototypes = true; break; } } } //------------------------------------------- // // Specific targets (application, library or java) // Prepare in case prototype files are needed // //------------------------------------------- m_PROTOTARGET = ""; //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes) if (need_prototypes) { m_PROTOTARGET = m_CONSTITUENT; m_PROTOTARGET += "PROTOS"; } if (m_LINKMACRO == "java") { if (is_library) { jar_header_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS); } else { java_header_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS); } } else { if (is_library) { library_header_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_PROTOTARGET); } else { application_header_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_PROTOTARGET); } } //---------------------------------------------------- // // Preparing prototype files. // //---------------------------------------------------- //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes) if (need_prototypes) { for (i = 0; i < m_source_files.size (); i++) { const SourceFile& file = m_source_files[i]; Language& language = file.language (); if (language.prototypes) { prepare_proto_file (file.name ()); } } if (m_PROTOSTAMPS != "") { protos_header_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_PROTOSTAMPS); } if (protonames != "") { for (i = 0; i < m_source_files.size (); i++) { const SourceFile& file = m_source_files[i]; Language& language = file.language (); if (language.prototypes) { proto_file_action (file.name (), constituent); } } } } //---------------------------------------------------- // // Preparing the library. // //---------------------------------------------------- if (m_OBJS != "") { if (m_LINKMACRO == "java") { if (is_library) { cmt_string classes = m_OBJS.value; classes.replace_all ("$(javabin)", ""); classes.replace_all (srcdir.c_str (), ""); m_CLASSES = classes; jar_fragment.copy (m_output_file, constituent.variables, 4, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS, &m_CLASSES); } } else { if (is_library) { if (constituent.no_share) { library_no_share_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS); } else { library_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS); } } else { application_fragment.copy (m_output_file, constituent.variables, 4, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS, &m_LINKMACRO); } } } if (constituent.build_triggers) { dependencies_and_triggers_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_LINE); } else { dependencies_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_LINE); } //---------------------------------------------------- // // Building actual individual targets. // //---------------------------------------------------- for (i = 0; i < m_source_files.size (); i++) { SourceFile& file = m_source_files[i]; Language& language = file.language (); if (language == "java") { java_file_action (file, constituent); } else { module_file_action (file, constituent); } } if (m_PACKOS9) { if (os9sources != "") { // // Generate transfers to the OS9 area. // m_ALLOS9SOURCES = ""; allsources = ""; } } /* for file in `cmt_sort_line.csh ${os9sources}` ; do if test `echo ${file} | grep '$(src)'` ; then name=`echo ${file} | sed 's#$(src)##'` ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}" allsources="${allsources} ${file}" elif test `echo ${file} | grep '$(inc)'` ; then name=`echo ${file} | sed 's#$(inc)##'` ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}" allsources="${allsources} ${file}" fi done if test ! "${ALLOS9SOURCES}" = "" ; then sed -e "`subs_vars ALLOS9SOURCES`" \ ${os9_header_fragment} \ >>${output} for FULLNAME in ${allsources} ; do NAME=`echo ${FULLNAME} | sed -e 's#$(src)##' -e 's#$(inc)##'` sed -e "`subs_vars NAME FULLNAME`" \ ${os9_fragment} \ >>${output} done fi fi fi */ // // Generate package cleanup operations. // cleanup_header_fragment.copy (m_output_file, constituent.variables, 2, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes) if (need_prototypes) { if (protos != "") { m_FULLNAME = protos; cleanup_fragment.copy (m_output_file, constituent.variables, 1, &m_FULLNAME); m_FULLNAME = m_PROTOSTAMPS; cleanup_fragment.copy (m_output_file, constituent.variables, 1, &m_FULLNAME); } } if (m_LINKMACRO == "java") { cleanup_java_fragment.copy (m_output_file, constituent.variables, 1, &m_OBJS); if (!is_library) { if (constituent.need_check) { check_java_fragment.copy (m_output_file, constituent.variables, 2, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } } } else { if (is_library) { cleanup_library_fragment.copy (m_output_file, constituent.variables, 2, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } else { cleanup_application_fragment.copy (m_output_file, constituent.variables, 2, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); if (m_OBJS != "") { cleanup_objects_fragment.copy (m_output_file, constituent.variables, 3, &m_OBJS, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } if (constituent.need_check) { check_application_fragment.copy (m_output_file, constituent.variables, 2, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } } } terminate (); } //-------------------------------------------------- DocumentGenerator::DocumentGenerator () { document_header_fragment.set ("document_header"); } //-------------------------------------------------- void DocumentGenerator::reset () { AnyDocumentGenerator::reset (); document_header_fragment.reset (); } //-------------------------------------------------- void DocumentGenerator::build (const cmt_string& package, const Constituent& constituent) { static cmt_string names; static cmt_string output_dir; static cmt_string name; static cmt_string full_name; static cmt_string compressed_name; static cmt_string suffix; static cmt_string output_suffix; static cmt_string fragment_suffix; reset (); if (!prepare_output (package, constituent)) return; is_library = false; is_application = false; m_GENERATOR = constituent.generator; m_TITLE = "Document"; int i; cout << m_TITLE << " " << m_CONSTITUENT << endl; // // Prepare the include paths. // const CmtSystem::cmt_string_vector& includes = constituent.includes; for (i = 0; i < includes.size (); i++) { const cmt_string& subdir = includes[i]; m_PACKINCLUDES += " -I"; m_PACKINCLUDES += subdir; } // // Get the fragment associated with the document style // FragmentHandle fragment (m_GENERATOR); fragment_suffix = fragment.suffix (); output_suffix = "."; if (fragment_suffix == "") { output_suffix += fragment.name (); } else { output_suffix += fragment_suffix; } // // Scan the sources. // const CmtSystem::cmt_string_vector& sources = constituent.modules; const cmt_vector& excludes = constituent.exclude_exprs; const cmt_vector& selects = constituent.select_exprs; m_LINE = ""; for (i = 0; i < sources.size (); i++) { cmt_string& file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; static CmtSystem::cmt_string_vector files; int count = get_all_files (full_name, excludes, selects, files); filter_path (full_name); if (count > 0) { m_LINE += full_name; m_LINE += " "; } for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { analyze_file (name, constituent.name, output_suffix); } } } fill_outputs (); prepare_use_context (); m_DATE = CmtSystem::now (); m_USER = CmtSystem::user (); m_PACKAGE = package; if (constituent.has_target_tag) { m_HASTARGETTAG = "has_target_tag"; } else { m_HASTARGETTAG = "has_no_target_tag"; } make_header_fragment.copy (m_output_file, constituent.variables, 7, &m_TITLE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_USER, &m_DATE, &m_PACKAGE, &m_HASTARGETTAG); const cmt_string& header = fragment.header (); // // If the document type specifies a header, use it . // otherwise, use the default document header fragment. // if (header != "") { FragmentHandle header_fragment (header); header_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS); } else { document_header_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS); } if (fragment.need_dependencies ()) { dependencies_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_LINE); } else { for (i = 0; i < sources.size (); i++) { cmt_string& file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; static CmtSystem::cmt_string_vector files; get_all_files (full_name, excludes, selects, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { static cmt_string s; static cmt_string n; CmtSystem::get_dot_suffix (name, s); CmtSystem::basename (name, s, n); CmtSystem::get_suffix (name, s); fprintf (m_output_file, "%s_%s_dependencies = %s\n", n.c_str (), s.c_str (), name.c_str ()); } } } } m_SUFFIX = fragment_suffix; for (i = 0; i < m_source_files.size (); i++) { SourceFile& file = m_source_files[i]; const cmt_string& file_name = file.name (); m_FULLNAME = file_name; CmtSystem::get_dot_suffix (file_name, suffix); CmtSystem::basename (file_name, suffix, m_NAME.value); CmtSystem::dirname (file_name, m_FILEPATH.value); if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator (); filter_path (m_FILEPATH.value); CmtSystem::basename (file_name, m_FILENAME.value); CmtSystem::get_dot_suffix (m_FILENAME.value, m_FILESUFFIX.value); if (!CmtSystem::test_file (file_name) && !CmtSystem::test_directory (file_name)) { cerr << "#CMT> Warning: Source file " << file_name << " not found" << endl; } filter_path (m_FULLNAME.value); fragment.copy (m_output_file, constituent.variables, 8, &m_FILEPATH, &m_SUFFIX, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_FILENAME, &m_NAME, &m_FULLNAME, &m_FILESUFFIX); } const cmt_string& trailer = fragment.trailer (); if (trailer != "") { FragmentHandle trailer_fragment (trailer); trailer_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS); } // // Generate package cleanup operations. // cleanup_header_fragment.copy (m_output_file, constituent.variables, 2, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); terminate (); } //-------------------------------------------------- bool DocumentGenerator::analyze_file (const cmt_string& file, const cmt_string& constituent_name, const cmt_string& output_suffix) { static cmt_string output_dir; static cmt_string suffix; static cmt_string name; static cmt_string obj; if (!CmtSystem::test_file (file) && !CmtSystem::test_directory (file)) { cerr << "#CMT> Warning: Source file " << file << " not found" << endl; } CmtSystem::dirname (file, output_dir); output_dir += CmtSystem::file_separator (); filter_path (output_dir); CmtSystem::get_suffix (file, suffix); CmtSystem::basename (file, suffix, name); //obj = output_dir; obj = "$("; obj += constituent_name; obj += "_output)"; obj += name; obj += output_suffix; SourceFile& source = m_source_files.add (); source.set (file, Language::null (), obj); return (true); } ReadmeGenerator::ReadmeGenerator () { readme_header_fragment.set ("readme_header"); readme_fragment.set ("readme"); readme_doc_fragment.set ("readme_doc"); readme_use_fragment.set ("readme_use"); readme_trailer_fragment.set ("readme_trailer"); } void ReadmeGenerator::reset () { CmtGenerator::reset (); readme_header_fragment.reset (); readme_fragment.reset (); readme_doc_fragment.reset (); readme_use_fragment.reset (); readme_trailer_fragment.reset (); } //-------------------------------------------------- void ReadmeGenerator::build (const CmtSystem::cmt_string_vector& arguments) { reset (); m_PACKAGE = Cmt::get_current_package (); m_VERSION = Cmt::get_current_version (); m_DATE = CmtSystem::now (); m_USER = CmtSystem::user (); cmt_string url; cmt_string doc; for (int i = 0; i < arguments.size (); i++) { cmt_string arg = arguments[i]; if (arg.substr (0, 5) == "-url=") { arg.substr (5, url); } else if (arg.substr (0, 5) == "-doc=") { arg.substr (5, doc); } } m_output_file_name = cmtdir + "README.html"; m_output_file = fopen (m_output_file_name.c_str (), "wb"); if (m_output_file != NULL) { readme_header_fragment.copy (m_output_file, 2, &m_PACKAGE, &m_VERSION); if (doc != "") { m_DOCPATH = doc; readme_doc_fragment.copy (m_output_file, 3, &m_PACKAGE, &m_VERSION, &m_DOCPATH); } readme_fragment.copy (m_output_file, 2, &m_PACKAGE, &m_VERSION); int number; const Use::UsePtrVector& uses = Use::get_ordered_uses (); for (number = 0; number < uses.size (); number++) { const Use* use = uses[number]; if (use == 0) continue; if (use->discarded) continue; Package* p = use->get_package (); if (p->is_cmt ()) continue; cmt_string selected_path; if (url == "") { selected_path = use->real_path; if (use->specified_path != "") { int pos = selected_path.find_last_of (use->specified_path); if (pos != cmt_string::npos) { selected_path.erase (pos); } } } else { selected_path = url; if (use->specified_path != "") { selected_path += CmtSystem::file_separator (); } } m_PACKAGEPATH = selected_path; m_PACKAGEPREFIX = use->specified_path; m_PACKAGE = use->get_package_name (); m_VERSION = use->version; m_MGRSTYLE = (use->style == mgr_style) ? "mgr" : "cmt"; readme_use_fragment.copy (m_output_file, 5, &m_PACKAGEPATH, &m_PACKAGEPREFIX, &m_PACKAGE, &m_VERSION, &m_MGRSTYLE); } m_PACKAGE = Cmt::get_current_package (); m_VERSION = Cmt::get_current_version (); readme_trailer_fragment.copy (m_output_file, 4, &m_PACKAGE, &m_VERSION, &m_DATE, &m_USER); terminate (); } } //-------------------------------------------------- class Prototyper : public FAwk { public: Prototyper (bool static_functions = false) : m_static_functions(static_functions) { if (m_static_functions) { m_suffix = "_static.phnew"; m_define_suffix = "_static_ph"; } else { m_suffix = ".phnew"; m_define_suffix = "_ph"; } } void begin () { m_running = false; static cmt_string suffix; static cmt_string name; CmtSystem::get_dot_suffix (m_file_name, suffix); CmtSystem::basename (m_file_name, suffix, name); m_out_file_name = ""; if (m_dir_name != "") { m_out_file_name = m_dir_name; m_out_file_name += CmtSystem::file_separator (); } m_out_file_name += name; m_out_file_name += m_suffix; CmtSystem::basename (m_file_name, suffix, m_file_name); m_output = fopen (m_out_file_name.c_str (), "wb"); if (m_output != 0) { fprintf (m_output, "#ifndef __%s%s__\n", m_file_name.c_str (), m_define_suffix.c_str ()); fprintf (m_output, "#define __%s%s__\n", m_file_name.c_str (), m_define_suffix.c_str ()); fprintf (m_output, "\n"); fprintf (m_output, "#ifdef __cplusplus\n"); fprintf (m_output, "extern \"C\" {\n"); fprintf (m_output, "#endif\n"); fprintf (m_output, "\n"); } else { stop (); } } void filter (const cmt_string& line) { char c = line[0]; if (!m_running) { if ((c == ' ') || (c == '/') || (c == '|') || (c == '\t') || (c == '#')) return; if (line.find ('(') == cmt_string::npos) { m_prev_line = line; return; } m_running = true; m_full_line = line; m_full_line.replace ("(", " ("); static CmtSystem::cmt_string_vector words; CmtSystem::split (m_full_line, " \t", words); const cmt_string& second = words[1]; if (second[0] == '(') { m_full_line = m_prev_line; m_full_line += " "; m_full_line += line; m_prev_line = ""; } } else { m_full_line += line; } if (line.find (')') == cmt_string::npos) return; m_running = false; if (m_full_line.find (';') != cmt_string::npos) return; if (m_full_line.find ("::") != cmt_string::npos) return; if (m_full_line.find ('<') != cmt_string::npos) return; if (m_full_line.find ('>') != cmt_string::npos) return; if (m_full_line.find ('{') != cmt_string::npos) return; if (m_full_line.find ('}') != cmt_string::npos) return; if (m_full_line.find ("typedef") != cmt_string::npos) return; if (m_full_line.find ("yy") != cmt_string::npos) return; if (m_full_line.find ("YY") != cmt_string::npos) return; if (m_static_functions) { if (m_full_line.find ("static") == cmt_string::npos) return; } else { if (m_full_line.find ("static") != cmt_string::npos) return; } m_full_line += ";"; if (m_output != 0) { fprintf (m_output, "%s\n", m_full_line.c_str ()); } } void end () { if (m_output != 0) { fprintf (m_output, "\n"); fprintf (m_output, "#ifdef __cplusplus\n"); fprintf (m_output, "}\n"); fprintf (m_output, "#endif\n"); fprintf (m_output, "\n"); fprintf (m_output, "#endif\n"); fprintf (m_output, "\n"); fclose (m_output); } CmtGenerator::check (m_out_file_name); } private: bool m_running; cmt_string m_out_file_name; FILE* m_output; bool m_static_functions; cmt_string m_full_line; cmt_string m_prev_line; cmt_string m_suffix; cmt_string m_define_suffix; }; //-------------------------------------------------- //-------------------------------------------------- void PrototypeGenerator::build (const cmt_string& file_name) { Prototyper prototyper; reset (); prototyper.run (file_name); } //-------------------------------------------------- void DefaultMakefileGenerator::build () { cmt_string makefile; //reset (); //--- Build a simple Makefile if none is installed #ifndef WIN32 bool need_makefile = false; makefile = cmtdir + "Makefile"; if (!CmtSystem::test_file (makefile)) { need_makefile = true; } else { static cmt_string s; s.read (makefile); if ((s.find ("METHODSROOT") != cmt_string::npos) || (s.find ("$(CMTROOT)/src/constituents.make") == cmt_string::npos)) { static cmt_string backup = makefile; backup += "_backup"; makefile += ".cmt"; if (!CmtSystem::test_file (makefile)) { FILE* file = fopen (backup.c_str (), "wb"); if (file != NULL) { cerr << "# " << endl; cerr << "#CMT> Warning: " << endl; cerr << "# A Makefile already exists " "but it does not provides " << endl; cerr << "# the recommended features " "for a full benefit of CMT" << endl; cerr << "# " << endl; cerr << "# CMT is now building " "a new 'Makefile.cmt' which you can use" << endl; cerr << "# to upgrade your current one." << endl; cerr << "# " << endl; s.write (file); fclose (file); need_makefile = true; } } } } if (need_makefile) { FILE* file = fopen (makefile.c_str (), "wb"); if (file != NULL) { fprintf (file, "include $(CMTROOT)/src/Makefile.header\n"); fprintf (file, "\n"); fprintf (file, "include $(CMTROOT)/src/constituents.make\n"); fprintf (file, "\n"); fclose (file); } } #endif #ifdef WIN32 makefile = cmtdir + "NMake"; if (Cmt::get_debug ()) { cout << "DefaultMakefileGenerator::build> pwd=" << CmtSystem::pwd () << " cmtdir=" << cmtdir << endl; } if (!CmtSystem::test_file (makefile)) { FILE* file = fopen (makefile.c_str (), "wb"); if (file != NULL) { fprintf (file, "!include $(CMTROOT)\\src\\NMakefile.header\n"); fprintf (file, "\n"); fprintf (file, "!include $(CMTROOT)\\src\\constituents.nmake\n"); fprintf (file, "\n"); fclose (file); } } #endif } MSDEVGenerator::MSDEVGenerator () { dsw_header_fragment.set ("dsw_header"); dsw_project_fragment.set ("dsw_project"); dsw_all_project_header_fragment.set ("dsw_all_project_header"); dsw_all_project_dependency_fragment.set ("dsw_all_project_dependency"); dsw_all_project_trailer_fragment.set ("dsw_all_project_trailer"); dsw_trailer_fragment.set ("dsw_trailer"); dsp_all_fragment.set ("dsp_all"); dsp_library_header_fragment.set ("dsp_library_header"); dsp_application_header_fragment.set ("dsp_application_header"); dsp_windows_header_fragment.set ("dsp_windows_header"); dsp_contents_fragment.set ("dsp_contents"); dsp_trailer_fragment.set ("dsp_trailer"); } void MSDEVGenerator::reset () { CmtGenerator::reset (); dsw_header_fragment.reset (); dsw_project_fragment.reset (); dsw_all_project_header_fragment.reset (); dsw_all_project_dependency_fragment.reset (); dsw_all_project_trailer_fragment.reset (); dsw_trailer_fragment.reset (); dsp_all_fragment.reset (); dsp_library_header_fragment.reset (); dsp_application_header_fragment.reset (); dsp_windows_header_fragment.reset (); dsp_contents_fragment.reset (); dsp_trailer_fragment.reset (); CmtSystem::cd (Cmt::get_current_dir ()); cmt_string branch = CmtSystem::current_branch (); if ((branch == "mgr") || (branch == "cmt")) { #ifdef WIN32 msdevdir = ".."; msdevdir += CmtSystem::file_separator (); msdevdir += "Visual"; if (!CmtSystem::test_directory (msdevdir)) { CmtSystem::mkdir (msdevdir); } msdevdir += CmtSystem::file_separator (); #endif } else { #ifdef WIN32 msdevdir = "."; msdevdir += CmtSystem::file_separator (); #endif } } int MSDEVGenerator::build_workspace (const Constituent::ConstituentVector& constituents) { reset (); const cmt_string& package = Cmt::get_current_package (); m_output_file_name = msdevdir + package + ".dswnew"; m_output_file = fopen (m_output_file_name.c_str (), "wb"); if (m_output_file != NULL) { m_PACKAGE = package; dsw_header_fragment.wincopy (m_output_file, 1, &m_PACKAGE); int i; dsw_all_project_header_fragment.wincopy (m_output_file, 1, &m_PACKAGE); for (i = 0; i < constituents.size (); i++) { const Constituent& constituent = constituents[i]; if (constituent.type == Library) { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; dsw_all_project_dependency_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } else { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; dsw_all_project_dependency_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } } dsw_all_project_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE); for (i = 0; i < constituents.size (); i++) { const Constituent& constituent = constituents[i]; if (constituent.type == Library) { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; dsw_project_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } else { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; dsw_project_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } } dsw_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE); terminate (); } m_output_file_name = msdevdir + "all.dspnew"; m_output_file = fopen (m_output_file_name.c_str (), "wb"); if (m_output_file != NULL) { dsp_all_fragment.wincopy (m_output_file, 1, &m_PACKAGE); terminate (); } return (0); } //-------------------------------------------------- int MSDEVGenerator::build_project (const Constituent& constituent) { reset (); const cmt_string& package = Cmt::get_current_package (); static cmt_string file; static cmt_string full_name; static cmt_string suffix; int i; m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; for (i = 0; i < constituent.includes.size (); i++) { const cmt_string& include = constituent.includes[i]; m_PACKINCLUDES += " -I" + include; } switch (constituent.type) { case Application: is_application = true; m_TITLE = "Application"; break; case Library: is_library = true; m_TITLE = "Library"; break; case Document: m_GENERATOR = constituent.generator; m_TITLE = "Document"; break; } m_PACKOS9 = constituent.need_OS9; const CmtSystem::cmt_string_vector& sources = constituent.modules; const cmt_vector& excludes = constituent.exclude_exprs; const cmt_vector& selects = constituent.select_exprs; //--- Build the constituents fragment ----- m_output_file_name = msdevdir + m_CONSTITUENT + ".dspnew"; m_output_file = fopen (m_output_file_name.c_str (), "wb"); if (m_output_file == NULL) return (0); m_PACKAGE = package; if (is_library) { if (constituent.no_share) { m_LIBRARYSUFFIX = "lib"; } else { m_LIBRARYSUFFIX = "arc"; } dsp_library_header_fragment.wincopy (m_output_file, constituent.variables, 4, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_LIBRARYSUFFIX); } else { if (constituent.windows) { dsp_windows_header_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } else { dsp_application_header_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } } for (i = 0; i < sources.size (); i++) { file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; static CmtSystem::cmt_string_vector files; get_all_files (full_name, excludes, selects, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { m_FULLNAME = name; if (m_output_file != NULL) { dsp_contents_fragment.wincopy (m_output_file, constituent.variables, 2, &m_PACKAGE, &m_FULLNAME); } } } } if (m_output_file != NULL) { dsp_trailer_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); terminate (); } return (0); } VSNETGenerator::VSNETGenerator () { sln_header_fragment.set ("sln_header"); sln_project_fragment.set ("sln_project"); sln_dependency_header_fragment.set ("sln_dependency_header"); sln_dependency_project_fragment.set ("sln_dependency_project"); sln_dependency_trailer_fragment.set ("sln_dependency_trailer"); sln_project_config_fragment.set ("sln_project_config"); sln_trailer_fragment.set ("sln_trailer"); vcproj_all_fragment.set ("vcproj_all"); vcproj_library_header_fragment.set ("vcproj_library_header"); vcproj_application_header_fragment.set ("vcproj_application_header"); vcproj_windows_header_fragment.set ("vcproj_windows_header"); vcproj_contents_fragment.set ("vcproj_contents"); vcproj_directory_header_fragment.set ("vcproj_directory_header"); vcproj_directory_trailer_fragment.set ("vcproj_directory_trailer"); vcproj_trailer_fragment.set ("vcproj_trailer"); } void VSNETGenerator::reset () { CmtGenerator::reset (); CmtSystem::cd (Cmt::get_current_dir ()); cmt_string branch = CmtSystem::current_branch (); if ((branch == "mgr") || (branch == "cmt")) { #ifdef WIN32 vsnetdir = ".."; vsnetdir += CmtSystem::file_separator (); vsnetdir += "Visual"; if (!CmtSystem::test_directory (vsnetdir)) { CmtSystem::mkdir (vsnetdir); } vsnetdir += CmtSystem::file_separator (); #endif } else { #ifdef WIN32 vsnetdir = "."; vsnetdir += CmtSystem::file_separator (); #endif } } void VSNETGenerator::pseudoGUID (const cmt_string& a, const cmt_string& b, const cmt_string& c, cmt_string& d) { char buf[64]; // make the guid in here static char hex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; int k = 0; int i; for (i = 0; (i < c.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = c[i]; for (i = 0; (i < a.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = a[i]; for (i = 0; (i < b.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = b[i]; for (; k < sizeof(buf); ++k) buf[k] = 0; // now use the buffer to format the output string // example: {3FE091FC-3738-4F2E-9723-E846B43F77AB} d = '{'; k = 0; for (i = 0; i < 4; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-'; for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-'; for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-'; for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-'; for (i = 0; i < 6; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '}'; } int VSNETGenerator::build_workspace (const Constituent::ConstituentVector& constituents) { reset (); const cmt_string& package = Cmt::get_current_package (); m_output_file_name = vsnetdir + package + ".slnnew"; Variable PACKAGE_GUID ("PACKAGE_GUID"); Variable CONSTITUENT_GUID ("CONSTITUENT_GUID"); Variable NUMBER ("NUMBER"); cmt_string guid; pseudoGUID (package, Cmt::get_current_version(), "", guid); PACKAGE_GUID = guid; m_output_file = fopen (m_output_file_name.c_str (), "wb"); if (m_output_file != NULL) { m_PACKAGE = package; sln_header_fragment.wincopy (m_output_file, 2, &m_PACKAGE, &PACKAGE_GUID); int i; for (i = 0; i < constituents.size (); i++) { const Constituent& constituent = constituents[i]; pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid); CONSTITUENT_GUID = guid; if (constituent.type == Library) { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; sln_project_fragment.wincopy (m_output_file, constituent.variables, 4, &m_PACKAGE, &m_CONSTITUENT, &PACKAGE_GUID, &CONSTITUENT_GUID); } else { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; sln_project_fragment.wincopy (m_output_file, constituent.variables, 4, &m_PACKAGE, &m_CONSTITUENT, &PACKAGE_GUID, &CONSTITUENT_GUID); } } sln_dependency_header_fragment.wincopy (m_output_file, 1, &m_PACKAGE); for (i = 0; i < constituents.size (); i++) { const Constituent& constituent = constituents[i]; pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid); CONSTITUENT_GUID = guid; cmt_string num; num = (char)('0' + i); NUMBER = num; if (constituent.type == Library) { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; sln_dependency_project_fragment.wincopy (m_output_file, constituent.variables, 5, &m_PACKAGE, &m_CONSTITUENT, &PACKAGE_GUID, &CONSTITUENT_GUID, &NUMBER); } else { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; sln_dependency_project_fragment.wincopy (m_output_file, constituent.variables, 5, &m_PACKAGE, &m_CONSTITUENT, &PACKAGE_GUID, &CONSTITUENT_GUID, &NUMBER); } } sln_dependency_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE); for (i = 0; i < constituents.size (); i++) { const Constituent& constituent = constituents[i]; pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid); CONSTITUENT_GUID = guid; if (constituent.type == Library) { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; sln_project_config_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &CONSTITUENT_GUID); } else { m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; sln_project_config_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &CONSTITUENT_GUID); } } sln_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE); terminate (); } m_output_file_name = vsnetdir + "all.vcprojnew"; m_output_file = fopen (m_output_file_name.c_str (), "wb"); if (m_output_file != NULL) { vcproj_all_fragment.wincopy (m_output_file, 1, &m_PACKAGE); terminate (); } return (0); } int VSNETGenerator::build_project (const Constituent& constituent) { reset (); const cmt_string& package = Cmt::get_current_package(); static cmt_string file; static cmt_string full_name; static cmt_string suffix; static Variable GUID("GUID"); int i; // Directory Support int dir_pos; int file_pos; int src_pos; int iSFFilter = 0; cmt_string directory; cmt_string new_dir; bool need_trailer = false; m_CONSTITUENT = constituent.name; // make up a pseudo-GUID from the constituent-pacakge-version combination cmt_string guid; pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid); GUID = guid; for (i = 0; i < constituent.includes.size (); i++) { const cmt_string& include = constituent.includes[i]; m_PACKINCLUDES += " -I" + include; } switch (constituent.type) { case Application: is_application = true; m_TITLE = "Application"; break; case Library: is_library = true; m_TITLE = "Library"; break; case Document: m_GENERATOR = constituent.generator; m_TITLE = "Document"; break; } m_PACKOS9 = constituent.need_OS9; const CmtSystem::cmt_string_vector& sources = constituent.modules; const cmt_vector& excludes = constituent.exclude_exprs; const cmt_vector& selects = constituent.select_exprs; //--- Build the constituents fragment ----- cmt_string output; m_output_file_name = vsnetdir + m_CONSTITUENT + ".vcprojnew"; m_output_file = fopen (m_output_file_name.c_str (), "wb"); if (m_output_file == NULL) return (0); m_PACKAGE = package; if (is_library) { if (constituent.no_share) { m_LIBRARYSUFFIX = "lib"; } else { m_LIBRARYSUFFIX = "arc"; } vcproj_library_header_fragment.wincopy (m_output_file, constituent.variables, 4, &m_PACKAGE, &m_CONSTITUENT, &GUID, &m_LIBRARYSUFFIX); } else { if (constituent.windows) { vcproj_windows_header_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &GUID); } else { vcproj_application_header_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &GUID); } } for (i = 0; i < sources.size (); i++) { file = sources[i]; set_full_name (full_name, file); if (full_name == "") continue; static CmtSystem::cmt_string_vector files; get_all_files (full_name, excludes, selects, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { m_FULLNAME = name; // Add Directory Support here // Step 1: Parse into "..\src\" "directory" "\filename.cxx" // find ..\ ; src_pos = name.find('\\'); // Finds ..\src\ ; dir_pos = name.find(src_pos+1, '\\') + 1; // Finds ..\src\..\astro\ ; file_pos = name.find_last_of('\\'); // Debug only //printf("%40s, %i, %i, %i;\n", name src_pos, dir_pos, file_pos); // If dir_pos == file_pos, then we have ../src/filename.cxx // If dir_pos > file_pos, then we have ../filename.cxx or something odd. // Step 2: see if it is or is not a ../src/ directory. if ((dir_pos < file_pos) && (dir_pos > src_pos)) { new_dir = name.substr (dir_pos, file_pos-dir_pos); new_dir.replace( "..\\", ""); // All names are relative to package/Visual, // so we want to ditch the prevailing ..\ ; // which all of them have. } else { new_dir = "Source Files NN"; } // Step 3: Add directory structure to vcproj file. if (new_dir != directory) // Detects a change in directory { directory = new_dir; // Step 3a: Add a when neccessary. if (need_trailer == false) { // Ensure that no trailing is placed incorrectly. need_trailer = true; } else { vcproj_directory_trailer_fragment.wincopy (m_output_file, constituent.variables, 1, &m_PACKAGE); } // Step 3b: Add a when neccessary. if ((dir_pos < file_pos) && (dir_pos > src_pos)) { // Add m_DIRNAME = new_dir; vcproj_directory_header_fragment.wincopy (m_output_file, constituent.variables, 2, &m_PACKAGE, &m_DIRNAME); } else { // Ensure that no is placed incorrectly. // This is the case of the file being in ../src // which requires no directory. Thus no filter start or end tag is needed. need_trailer = false; } } if (m_output_file != NULL) { vcproj_contents_fragment.wincopy (m_output_file, constituent.variables, 2, &m_PACKAGE, &m_FULLNAME); } } } } if (need_trailer == true) { // Add a trailing for directory support. vcproj_directory_trailer_fragment.wincopy (m_output_file, constituent.variables, 1, &m_PACKAGE); } if (m_output_file != NULL) { vcproj_trailer_fragment.wincopy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); terminate (); } return (0); } MakeSetupGenerator::MakeSetupGenerator () { make_setup_header_fragment.set ("make_setup_header"); make_setup_fragment.set ("make_setup"); } void MakeSetupGenerator::reset () { CmtGenerator::reset (); make_setup_header_fragment.reset (); make_setup_fragment.reset (); } void MakeSetupGenerator::build (const cmt_string& package) { reset (); m_PACKAGE = package; cmt_string file_name = "setup."; if (Cmt::build_nmake ()) { file_name += "nmake"; } else { file_name += "make"; } cmt_string new_file_name = file_name; new_file_name += "new"; m_output_file = fopen (new_file_name, "wb"); if (m_output_file != NULL) { int number; const Use::UsePtrVector& uses = Use::get_ordered_uses (); const Constituent::ConstituentVector& constituents = Constituent::constituents (); cmt_string temp; make_setup_header_fragment.copy (m_output_file, 1, &m_PACKAGE); for (number = 0; number < uses.size (); number++) { const Use* use = uses[number]; if (use->discarded) continue; if (use->real_path != "") { temp = use->prefix; temp += "ROOT = "; temp += use->get_full_path (); fprintf (m_output_file, "%s\n", temp.c_str()); } } temp = "use_requirements = "; temp += "requirements "; for (number = 0; number < uses.size (); number++) { const Use* use = uses[number]; if (use->discarded) continue; if (use->real_path != "") { temp += "$("; temp += use->prefix; temp += "ROOT)"; temp += CmtSystem::file_separator (); switch (use->style) { case cmt_style: temp += "cmt"; break; case mgr_style: temp += "mgr"; break; } temp += CmtSystem::file_separator (); temp += "requirements "; } } fprintf (m_output_file, "%s\n", temp.c_str()); temp = "constituents = $(constituents)"; Symbol::expand (temp); fprintf (m_output_file, "%s\n", temp.c_str()); make_setup_fragment.copy (m_output_file, 1, &m_PACKAGE); fclose (m_output_file); //--- Complete the operation -------------- commit (new_file_name); } /* for option in $* do case ${option} in args-tag=*) tag=${option} tag=`echo "${tag}" | sed -e 's/args.tag=//'` ;; -tag=*) tag=args${option} tag=`echo "${tag}" | sed -e 's/args.tag=//'` ;; esac done if test "${tag}" = "" ; then tag=${CMTCONFIG} fi build_shell_setup_files ${tag} now=`date` */ } ConstituentsMakefileGenerator::ConstituentsMakefileGenerator () { constituents_header_fragment.set ("constituents_header"); constituents_trailer_fragment.set ("constituents_trailer"); group_fragment.set ("group"); constituent_fragment.set ("constituent"); check_application_header_fragment.set ("check_application_header"); } void ConstituentsMakefileGenerator::reset () { CmtGenerator::reset (); constituents_header_fragment.reset (); constituents_trailer_fragment.reset (); group_fragment.reset (); constituent_fragment.reset (); check_application_header_fragment.reset (); } //-------------------------------------------------- void ConstituentsMakefileGenerator::build (const cmt_string& package, const CmtSystem::cmt_string_vector& arguments) { reset (); cmt_string file_name; if (arguments.size () > 0) { cmt_string arg = arguments[0]; if (arg.substr (0, 5) == "-out=") { arg.erase (0, 5); file_name = arg; } } if (file_name == "") { file_name = "constituents."; //--- Build the constituents fragment ----- if (Cmt::build_nmake ()) { file_name += "nmake"; } else { file_name += "make"; } } cmt_string save_file_name = file_name; save_file_name += "sav"; if (CmtSystem::test_file (file_name)) { rename (file_name, save_file_name); } cmt_string new_file_name = file_name; new_file_name += "new"; m_output_file = fopen (new_file_name, "wb"); if (m_output_file != NULL) { int number; const Constituent::ConstituentVector& constituents = Constituent::constituents (); m_PACKAGE = package; constituents_header_fragment.copy (m_output_file, 1, &m_PACKAGE); m_GROUP = "all"; group_fragment.copy (m_output_file, 1, &m_GROUP); const Group::GroupVector& groups = Group::groups (); for (number = 0; number < groups.size (); number++) { const Group& group = groups[number]; m_GROUP = group.name (); group_fragment.copy (m_output_file, 1, &m_GROUP); } for (number = 0; number < constituents.size (); number++) { const Constituent& constituent = constituents[number]; m_CONSTITUENT = constituent.name; m_CONSTITUENTSUFFIX = constituent.suffix; m_LINE = ""; if (constituent.has_target_tag) { m_HASTARGETTAG = "has_target_tag"; } else { m_HASTARGETTAG = "has_no_target_tag"; } constituent_fragment.copy (m_output_file, constituent.variables, 5, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_LINE, &m_HASTARGETTAG); if (constituent.need_check) { check_application_header_fragment.copy (m_output_file, constituent.variables, 3, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX); } } constituents_trailer_fragment.copy (m_output_file, 0); fclose (m_output_file); commit (new_file_name); } } /** With this Awk filter, we analyze an existing dependency file. We get the source name in each line The list of sources is maintained in m_sources A source is stored in the form _ (instead of .) */ class DependencyFilter : public Awk { public: DependencyFilter () { } void begin () { m_sources = ""; } void filter (const cmt_string& line) { int pos = line.find ("_dependencies = "); if (pos == cmt_string::npos) return; cmt_string s = line; s.erase (pos); m_sources += " "; m_sources += s; m_sources += " "; //pos = s.find_last_of ("_"); //if (pos != cmt_string::npos) s[pos] = "." } void add_source (const cmt_string& file_name) { static cmt_string suffix; static cmt_string name; CmtSystem::get_dot_suffix (file_name, suffix); CmtSystem::basename (file_name, suffix, name); CmtSystem::get_suffix (file_name, suffix); cmt_string s = " "; s += name; s += "_"; s += suffix; s += " "; if (m_sources.find (s) == cmt_string::npos) { m_sources += s; } } bool has_source (const cmt_string& file_name) const { static cmt_string suffix; static cmt_string name; CmtSystem::get_dot_suffix (file_name, suffix); CmtSystem::basename (file_name, suffix, name); CmtSystem::get_suffix (file_name, suffix); cmt_string s = " "; s += name; s += "_"; s += suffix; s += " "; if (m_sources.find (s) == cmt_string::npos) { return (false); } else { return (true); } } cmt_string& get_sources () { return (m_sources); } private: cmt_string m_sources; }; void DependencyGenerator::build (const CmtSystem::cmt_string_vector& arguments) { reset (); prepare_use_context (); m_stamps = true; const cmt_string& name = arguments[0]; //cerr << "name=" << name << endl; m_constituent = Constituent::find (name); if (m_constituent == 0) { // Error : wrong constituent name... return; } const Constituent& constituent = *m_constituent; cmt_string file_name; cmt_string full_name; cmt_string compressed_name; cmt_string suffix; cmt_string dependencies; // // Now prepare the output file names // cmt_string branch = CmtSystem::current_branch (); if ((branch == "mgr") || (branch == "cmt")) { Use& current_use = Use::current (); Package* p = current_use.get_package (); if (p->is_cmt ()) { m_bin = "../"; m_bin += CmtSystem::getenv ("CMTBIN"); m_bin += CmtSystem::file_separator (); } else { m_bin = "${bin}"; } Symbol::expand (m_bin); //cerr << "m_output_file_name=" << m_output_file_name << endl; //cerr << "current_tag=" << Cmt::current_tag << endl; } else { m_bin = "."; m_bin += CmtSystem::file_separator (); } m_output_file_name = m_bin; m_output_file_name += name; m_output_file_name += "_"; m_output_file_name += "dependencies."; if (Cmt::build_nmake ()) { m_output_file_name += "nmake"; } else { m_output_file_name += "make"; } // // New read the existing dependency file if any and filter it to // extract the source names // static DependencyFilter filter; dependencies.read (m_output_file_name); filter.run (dependencies); // // Scan the sources. // // // We have to rebuild the dependencies for : // // o all sources if the parameter -all_sources has been received // o otherwise, // + all source names provided in the argument list (if any) // + all source names missing from the existing dependency file (if any) // const CmtSystem::cmt_string_vector& sources = constituent.modules; const cmt_vector& excludes = constituent.exclude_exprs; const cmt_vector& selects = constituent.select_exprs; bool all_sources = false; int source_number = arguments.size (); int i; //cerr << "source_number=" << source_number << endl; for (i = source_number-1; i >= 0; i--) { file_name = arguments[i]; //cerr << "file_name=" << file_name << endl; // Get rid of files that may come from the makefile fragment if (file_name.find ("requirements") != cmt_string::npos) source_number--; else if (file_name.find (".make") != cmt_string::npos) source_number--; else if (file_name == "-all_sources") { source_number = sources.size (); all_sources = true; } else if (file_name == "-no_stamps") { source_number--; m_stamps = false; } } if (all_sources) { for (i = 0; i < sources.size (); i++) { file_name = sources[i]; set_full_name (full_name, file_name); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; static CmtSystem::cmt_string_vector files; get_all_files (full_name, excludes, selects, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { const cmt_string& line = build (name); //cout << ">>> line=[" << line << "]" << endl; add_line_to_text (line, dependencies); } } } } else { for (i = 1; i < source_number; i++) { file_name = arguments[i]; set_full_name (full_name, file_name); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; const cmt_string& line = build (full_name); //cout << ">>> name2=" << full_name << endl; add_line_to_text (line, dependencies); //cout << ">>from deps : " << filter.get_sources () << endl; filter.add_source (full_name); } //cout << ">>from deps : " << filter.get_sources () << endl; // Now : are there still any missing source file in dependencies?? for (i = 0; i < sources.size (); i++) { file_name = sources[i]; set_full_name (full_name, file_name); if (full_name == "") continue; CmtSystem::compress_path (full_name, compressed_name); full_name = compressed_name; static CmtSystem::cmt_string_vector files; get_all_files (full_name, excludes, selects, files); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name != "") { if (!filter.has_source (name)) { const cmt_string& line = build (name); //cout << ">>> name3=" << name << endl; add_line_to_text (line, dependencies); } } } } } FILE* f = fopen (m_output_file_name.c_str (), "wb"); if (f == 0) { cerr << "Cannot open " << m_output_file_name << " for write" << endl; } else { dependencies.write (f); fclose (f); } } //-------------------------------------------------- // o text contains lines with a pattern like : // key = xxxxx // // o line follows the same pattern // // This function appends to only if the key found in // is not found in //-------------------------------------------------- void DependencyGenerator::add_line_to_text (const cmt_string& line, cmt_string& text) { static const cmt_string empty; int pos = line.find (" = "); if (pos != cmt_string::npos) { static cmt_string key; line.substr (0, pos + 3, key); pos = text.find (key); if (pos != cmt_string::npos) { // The key in line exists in text. // Now check if the key is exactly the same. if ((pos == 0) || (text[pos -1] == '\n')) { // The key is either in the first line or // exactly matches '^key = ...' int nl = text.find (pos, "\n"); if (nl != cmt_string::npos) { static cmt_string old; text.substr (pos, nl - pos + 1, old); text.replace (old, empty); } else { text.erase (pos); } } } } if (line != "") { text += line; text += "\n"; } } cmt_string DependencyGenerator::build (const cmt_string& file_name) { Log; const Constituent& constituent = *m_constituent; static cmt_string full_name; static cmt_string suffix; static cmt_string name; static cmt_string line; full_name = ""; line = ""; if (!CmtSystem::absolute_path (file_name)) { full_name = srcdir; } full_name += file_name; CmtSystem::get_dot_suffix (full_name, suffix); CmtSystem::basename (full_name, suffix, name); CmtSystem::get_suffix (full_name, suffix); if (name == "requirements") return (line); const CmtSystem::cmt_string_vector& deps = m_deps_builder.run (full_name); line = name; line += "_"; line += suffix; line += "_dependencies = "; filter_path (full_name); #ifdef WIN32 static const char quote = '\"'; #else static const char quote = ' '; #endif line += quote; line += full_name; line += quote; for (int j = 0; j < deps.size (); j++) { cmt_string d = deps[j]; log << "dep line = " << d << log_endl; filter_path (d); log << "filtered dep line = " << d << log_endl; line += " "; line += quote; line += d; line += quote; } Symbol::expand (line); if (m_stamps) { cmt_string stamp_output_base = constituent.name; stamp_output_base += "_deps"; cmt_string stamp_output = m_bin; stamp_output += stamp_output_base; if (!CmtSystem::mkdir (stamp_output)) { cerr << "Cannot create the binary output directory for this constituent" << endl; } stamp_output_base += CmtSystem::file_separator (); stamp_output_base += name; stamp_output_base += "_"; stamp_output_base += suffix; stamp_output_base += ".stamp"; stamp_output = m_bin; stamp_output += stamp_output_base; line += " $(bin)"; line += stamp_output_base; cmt_string old_stamp; if (CmtSystem::test_file (stamp_output)) { old_stamp.read (stamp_output); } if (line != old_stamp) { line.write (stamp_output); } } return (line); }