//----------------------------------------------------------- // 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" #include "cmt_error.h" #include #include "cmt_project.h" //-------------------------------------------------- AnyDocumentGenerator::AnyDocumentGenerator () { m_TITLE.set ("TITLE"); m_STRUCTURED_OUTPUT.set ("STRUCTURED_OUTPUT"); 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"); library_no_static_fragment.set ("library_no_static"); 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 (); library_no_static_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; CmtMessage::warning ("Source file " + file + " not found"); // 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 (CmtSystem::getenv("STRUCTURED_OUTPUT")!="" || Cmt::build_nmake ()) { obj += m_CONSTITUENT; 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 { 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 = ""; CmtMessage::warning ("Source file " + name + " cannot be rebuilt"); // cerr << "#CMT> Warning: Source file " << name << " cannot be rebuilt" << endl; } else { obj = ""; } } if (Cmt::get_debug ()) { cout << "LibraryGenerator::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 { CmtMessage::warning ("file " + m_FULLNAME + " not found"); // 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); m_DEPENDENCIESOPTS = language.dependencies_options (); } 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); CmtSystem::get_suffix (name, m_FILESUFFIX.value); if (fragment != 0) { // fragment->copy (m_output_file, constituent.variables, 10, 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_DEPENDENCIESOPTS); } 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 += m_FULLNAME.value; os9sources += " "; } } //-------------------------------------------------- void LibraryGenerator::fill_names_outputs () { bool l_first = true; bool o_first = true; m_LINE = ""; m_OBJS = ""; for (int i = 0; i < m_source_files.size (); i++) { const SourceFile& file = m_source_files[i]; const cmt_string name = file.name (); const cmt_string output = file.output (); Language& language = file.language (); if (output != "") { if (o_first) { o_first = false; } else { m_OBJS += " "; } m_OBJS += output; if (language == Language::null () || !language.native_dependencies ()) { if (l_first) { l_first = false; } else { m_LINE += " "; } m_LINE += name; } } if (Cmt::get_debug ()) { cout << "LibraryGenerator::fill_names_outputs>" << endl; cout << "name=" << name << " LINE=" << m_LINE << endl; cout << "output=" << output << " OBJS=" << m_OBJS << endl; } } filter_path (m_LINE.value); } //-------------------------------------------------- void LibraryGenerator::build (const cmt_string& package, const Constituent& constituent, bool& dependencies, const cmt_string& file_name) { 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, file_name)) 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; CmtMessage::info (m_TITLE + " " + m_CONSTITUENT); 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_names_outputs (); //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"; } m_HASDEPENDENCIES = "has_dependencies"; m_STRUCTURED_OUTPUT = "STRUCTURED_OUTPUT"; make_header_fragment.copy (m_output_file, constituent.variables, 9, &m_TITLE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_USER, &m_DATE, &m_PACKAGE, &m_HASTARGETTAG, &m_HASDEPENDENCIES, &m_STRUCTURED_OUTPUT ); 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 && constituent.no_static) { CmtMessage::warning (constituent.name + ": No shared or static library"); } else if (constituent.no_share) { library_no_share_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_OBJS); } else if (constituent.no_static) { library_no_static_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); } } } bool need_dependencies = false; for (i = 0; i < m_source_files.size (); i++) { const SourceFile& file = m_source_files[i]; Language& language = file.language (); if (language == Language::null () || !language.native_dependencies ()) { need_dependencies = true; break; } } dependencies = need_dependencies; if (constituent.build_triggers) { dependencies_and_triggers_fragment.copy (m_output_file, constituent.variables, 3, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_LINE); } else { if (need_dependencies) { 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 () { m_FILEEXTENSION.set ("FILEEXTENSION"); document_header_fragment.set ("document_header"); dependency_fragment.set ("dependency"); } //-------------------------------------------------- void DocumentGenerator::reset () { AnyDocumentGenerator::reset (); m_FILEEXTENSION = ""; document_header_fragment.reset (); dependency_fragment.reset (); } //-------------------------------------------------- void DocumentGenerator::build (const cmt_string& package, const Constituent& constituent, bool& dependencies, const cmt_string& file_name) { 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, file_name)) return; is_library = false; is_application = false; m_GENERATOR = constituent.generator; m_TITLE = "Document"; int i; // cout << m_TITLE << " " << m_CONSTITUENT << endl; CmtMessage::info (m_TITLE + " " + m_CONSTITUENT); // // 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_names_outputs (); // 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"; } m_HASDEPENDENCIES = fragment.need_dependencies () ? "has_dependencies" : "has_no_dependencies" ; make_header_fragment.copy (m_output_file, constituent.variables, 8, &m_TITLE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_USER, &m_DATE, &m_PACKAGE, &m_HASTARGETTAG, &m_HASDEPENDENCIES ); 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); } dependencies = fragment.need_dependencies (); 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]; */ for (i = 0; i < m_source_files.size (); i++) { SourceFile& file = m_source_files[i]; const cmt_string& name = file.name (); 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); m_FILENAME.value = m_NAME.value + suffix; //CmtSystem::basename (file_name, m_FILENAME.value); m_FILESUFFIX.value = suffix; //CmtSystem::get_dot_suffix (m_FILENAME.value, m_FILESUFFIX.value); CmtSystem::get_suffix (m_FILENAME.value, m_FILEEXTENSION .value); /* if (!CmtSystem::test_file (file_name) && !CmtSystem::test_directory (file_name)) { CmtMessage::warning ("Source file " + file_name + " not found"); } */ filter_path (m_FULLNAME.value); if (fragment.need_dependencies ()) { // ensure that ${CONSTITUENT}_dependencies.make gets rebuilt // whenever source file OR its dependencies change if (!dependency_fragment.copy (m_output_file, constituent.variables, 9, &m_FILEPATH, &m_SUFFIX, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_FILENAME, &m_NAME, &m_FULLNAME, &m_FILESUFFIX, &m_FILEEXTENSION)) return; } fragment.copy (m_output_file, constituent.variables, 9, &m_FILEPATH, &m_SUFFIX, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_FILENAME, &m_NAME, &m_FULLNAME, &m_FILESUFFIX, &m_FILEEXTENSION); } 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)) { CmtMessage::warning ("Source file " + file + " not found"); } //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 (); } else { CmtError::set (CmtError::file_access_error, m_output_file_name); } } //-------------------------------------------------- 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) { CmtMessage::warning ("\n" "# A Makefile already exists " "but it does not provide\n" "# the recommended features " "for a full benefit of CMT\n" "#\n" "# CMT is now building " "a new 'Makefile.cmt' which you can use\n" "# to upgrade your current one."); /* 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); CmtSystem::close_ostream (file, backup); // fclose (file); need_makefile = true; } else { CmtError::set (CmtError::file_access_error, backup); } } } } if (need_makefile) { FILE* file = fopen (makefile.c_str (), "wb"); if (file != NULL) { fprintf (file, "include $(CMTROOT)/src/Makefile.header\n" "\n" "include $(CMTROOT)/src/constituents.make\n" "\n"); CmtSystem::close_ostream (file, makefile); // fclose (file); } else { CmtError::set (CmtError::file_access_error, makefile); } } #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" "\n" "!include $(CMTROOT)\\src\\constituents.nmake\n" "\n"); CmtSystem::close_ostream (file, makefile); // fclose (file); } else { CmtError::set (CmtError::file_access_error, makefile); } } #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 (); } else { CmtError::set (CmtError::file_access_error, m_output_file_name); } 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 (); } else { CmtError::set (CmtError::file_access_error, m_output_file_name); } 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); CmtSystem::close_ostream (m_output_file, new_file_name); // fclose (m_output_file); //--- Complete the operation -------------- commit (new_file_name); } else { CmtError::set (CmtError::file_access_error, 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"); constituent_lock_fragment.set ("constituent_lock"); 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 (); constituent_lock_fragment.reset (); check_application_header_fragment.reset (); } //-------------------------------------------------- void ConstituentsMakefileGenerator::build (const cmt_string& package, const cmt_string& file) // const CmtSystem::cmt_string_vector& arguments) { reset (); cmt_string file_name (file); //, dir_name; // if (arguments.size () > 0) // { // cmt_string arg = arguments[0]; // if (arg.substr (0, 5) == "-out=") // { // arg.erase (0, 5); // file_name = arg; // } // else if (arg.substr (0, 8) == "-outdir=") // { // arg.erase (0, 8); // dir_name = arg; // } // } if (file_name == "") { file_name = "constituents."; //--- Build the constituents fragment ----- if (Cmt::build_nmake ()) { file_name += "nmake"; } else { file_name += "make"; } } // if (dir_name != "") // { // if (dir_name [dir_name.size () - 1] != CmtSystem::file_separator ()) // dir_name += CmtSystem::file_separator (); // file_name = dir_name + file_name; // } cmt_string save_file_name = file_name; save_file_name += "cmtsave"; 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); } bool lock = false; Symbol* lock_command_macro = Symbol::find ("lock_command"); if (lock_command_macro != 0) { cmt_string lock_command = lock_command_macro->resolve_macro_value (); if (lock_command != "") { Symbol* unlock_command_macro = Symbol::find ("unlock_command"); if (unlock_command_macro != 0) { cmt_string unlock_command = unlock_command_macro->resolve_macro_value (); if (unlock_command != "") { lock = true; } } } } 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"; } switch (constituent.type) { case Application: m_HASDEPENDENCIES = "has_dependencies"; break; case Library: m_HASDEPENDENCIES = "has_dependencies"; break; case Document: m_HASDEPENDENCIES = FragmentHandle (constituent.generator).need_dependencies () ? "has_dependencies" : "has_no_dependencies" ; break; } if (constituent.type == Document && lock == true) { constituent_lock_fragment.copy (m_output_file, constituent.variables, 6, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_LINE, &m_HASDEPENDENCIES, &m_HASTARGETTAG); } else { constituent_fragment.copy (m_output_file, constituent.variables, 6, &m_PACKAGE, &m_CONSTITUENT, &m_CONSTITUENTSUFFIX, &m_LINE, &m_HASDEPENDENCIES, &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); CmtSystem::close_ostream (m_output_file, new_file_name); // fclose (m_output_file); commit (new_file_name); } else { CmtError::set (CmtError::file_access_error, new_file_name); } } //-------------------------------------------------- PackagesMakefileGenerator::PackagesMakefileGenerator () { m_DEPENDENCIES.set ("DEPENDENCIES"); m_PACKAGEMGRPATH.set ("PACKAGEMGRPATH"); m_PACKAGEFULLNAME.set ("PACKAGEFULLNAME"); m_ISLOCAL.set ("ISLOCAL"); packages_header_fragment.set ("packages_header"); packages_trailer_fragment.set ("packages_trailer"); package_fragment.set ("package"); } void PackagesMakefileGenerator::reset () { CmtGenerator::reset (); m_DEPENDENCIES = ""; m_PACKAGEMGRPATH = ""; m_PACKAGEFULLNAME = ""; m_ISLOCAL = ""; packages_header_fragment.reset (); packages_trailer_fragment.reset (); package_fragment.reset (); } //-------------------------------------------------- void PackagesMakefileGenerator::build (const cmt_string& package, const cmt_string& file) { reset (); cmt_string file_name (file); if (file_name == "") { file_name = "packages."; if (Cmt::build_nmake ()) { file_name += "nmake"; } else { file_name += "make"; } } cmt_string save_file_name = file_name; save_file_name += "cmtsave"; 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) { m_PACKAGE = package; if (!packages_header_fragment.copy (m_output_file, 1, &m_PACKAGE)) return; Project* cur = Project::get_current (); Use::UsePtrVector uses (Use::get_ordered_uses ()); uses.push_back (&Use::current ()); cmt_string temp; for (int i = uses.size () - 1; i >= 0; i--) { Use* use = uses[i]; if (use->discarded) continue; if (use->m_hidden) continue; if (!use->located ()) continue; if (use->get_package ()->is_cmt ()) continue; if (use->get_project () == cur) m_ISLOCAL = "is_local"; else m_ISLOCAL = "is_not_local"; temp = use->get_full_path (); switch (use->style) { case cmt_style: temp += CmtSystem::file_separator (); temp += "cmt"; break; case mgr_style: temp += CmtSystem::file_separator (); temp += "mgr"; break; } #ifdef WIN32 temp += " "; #endif m_PACKAGEMGRPATH = temp; // fprintf (m_output_file, "%s\n", temp.c_str()); temp = ""; if (Symbol* s = Symbol::find (use->get_package_name () + "_offset")) { cmt_string o = s->build_macro_value (); if (o != "") { temp += o; temp += CmtSystem::file_separator (); } } else { CmtMessage::warning (CmtError::get_error_name (CmtError::symbol_not_found) + ": macro " + use->get_package_name () + "_offset"); } temp += use->get_package_name (); temp.replace_all (CmtSystem::file_separator (), "_"); #ifdef WIN32 temp += " "; #endif m_PACKAGEFULLNAME = temp; // fprintf (m_output_file, "%s\n", temp.c_str()); m_PACKAGE = use->get_package_name (); Use::UsePtrVector subuses; for (int i = 0; i < use->sub_uses.size (); i++) { if (use->sub_uses[i]->m_index >= 0 && !use->sub_uses[i]->discarded) { if (use->sub_uses[i]->m_hidden) continue; subuses.push_back (use->sub_uses[i]); } else { Use* au (Use::find_valid (use->sub_uses[i]->get_package_name ())); if (au) { subuses.push_back (au); } } } m_DEPENDENCIES = ""; for (int i = 0; i < subuses.size (); i++) { if (i != 0) { m_DEPENDENCIES += " " + subuses[i]->get_package_name (); } else { m_DEPENDENCIES += subuses[i]->get_package_name (); } } if (!package_fragment.copy (m_output_file, 5, &m_PACKAGE, &m_DEPENDENCIES, &m_PACKAGEMGRPATH, &m_PACKAGEFULLNAME, &m_ISLOCAL)) return; } if (Symbol* s = Symbol::find ("CMTINSTALLAREA")) { cmt_string o = s->build_macro_value (); Symbol::expand (o); if (o != "") { temp = "CMTINSTALLAREA="; temp += o; #ifdef WIN32 temp += " "; #endif fprintf (m_output_file, "%s\n", temp.c_str()); } } if (!packages_trailer_fragment.copy (m_output_file, 0)) return; CmtSystem::close_ostream (m_output_file, new_file_name); // fclose (m_output_file); commit (new_file_name); } else { CmtError::set (CmtError::file_access_error, 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::reset () { CmtGenerator::reset (); m_deps_builder.clear (); m_stamps = true; m_name = "cmt_unnamed"; } //-------------------------------------------------- void DependencyGenerator::prepare_includes () { cmt_string path; cmt_string substitution; Use* use = &Use::current (); // m_deps_builder.clear (); if (use->include_path != "none") { if (use->include_path == "") { m_deps_builder.add (incdir, "$(src)"); } else { substitution = use->include_path; path = substitution; Symbol::expand (path); CmtSystem::reduce_file_separators (path); m_deps_builder.add (path, substitution); } } m_deps_builder.add_includes (*use); Use::UsePtrVector& uses = Use::get_ordered_uses (); if (uses.size () > 0) { int number; for (number = 0; number < uses.size (); number++) { use = uses[number]; if (use->discarded) continue; if (use->real_path != "") { if (use->include_path != "none") { if (use->include_path == "") { use->get_full_path (path); path += CmtSystem::file_separator (); path += "src"; substitution = "$("; substitution += use->prefix; substitution += "ROOT)"; substitution += CmtSystem::file_separator (); substitution += "src"; substitution += CmtSystem::file_separator (); } else { substitution = use->include_path; path = substitution; Symbol::expand (path); CmtSystem::reduce_file_separators (path); } m_deps_builder.add (path, substitution); } m_deps_builder.add_includes (*use); } } } } //-------------------------------------------------- void DependencyGenerator::prepare_header_file_filters () { const Use* current_use = &Use::current (); Use::UsePtrVector uses (Use::get_ordered_uses ()); uses.push_back (&Use::current ()); bool current_only (true); for (int i = uses.size () - 1; i >= 0; i--) { const Use* use = uses[i]; //cerr << "prepare_header_file_filters(0)> " << use->get_package_name () << "[" << use->get_index () << "]\n"; if (use->discarded) continue; if (use->m_hidden) continue; if (!use->located ()) continue; if (current_only && use != current_use) current_only = false; cmt_string package_name = use->get_package_name (); if (package_name == "CMT") continue; const Symbol* filter_macro = Symbol::find (package_name + "_header_file_filter"); if (filter_macro == 0) continue; const cmt_string filter_expr (filter_macro->resolve_macro_value ()); if (filter_expr.size () == 0) continue; const Symbol* stamp_macro = Symbol::find (package_name + "_header_file_stamp"); cmt_string stamp; if (stamp_macro != 0) { stamp = stamp_macro->resolve_macro_value (); } else { use->get_full_path (stamp); switch (use->style) { case cmt_style: stamp += CmtSystem::file_separator (); stamp += "cmt"; break; case mgr_style: stamp += CmtSystem::file_separator (); stamp += "mgr"; break; } stamp += CmtSystem::file_separator (); stamp += "cmt_header_file.stamp"; //stamp += "cmt_all_headers.stamp"; ///cmt/cmt_all_headers.stamp } if (!CmtSystem::test_file (stamp)) continue; //cerr << "0: adding filter: " << use->get_package_name () << "[" << use->get_index () << "]\n"; cmt_regexp* filter = new cmt_regexp (filter_expr); //cmt_regexp* filter = new cmt_regexp (filter_macro->resolve_macro_value ()); assert (filter != 0); m_deps_builder.add_header_filter (use, filter, stamp); } if (current_only) { // we are most likely reading dependencies[_CONSTITUENT].in without CMT for (int number = 0; number < Symbol::symbol_number (); number++) { const Symbol& symbol = Symbol::symbol (number); if (symbol.type != Symbol::SymbolMacro) continue; int r = symbol.name.find_last_of ("_header_file_filter"); if (r == cmt_string::npos || (r + 19) != symbol.name.size () || r == 0) continue; const cmt_string filter_expr (symbol.resolve_macro_value ()); if (filter_expr.size () == 0) continue; cmt_string package_name = symbol.name.substr(0, r); const Use* use = Use::find (package_name); if (use == current_use) continue; if (0 != use && use->discarded) continue; if (0 != use && use->m_hidden) continue; if (0 != use && !use->located ()) continue; //Symbol* filter_macro = Symbol::find (package_name + "_header_file_filter"); //if (filter_macro == 0) continue; const Symbol* stamp_macro = Symbol::find (package_name + "_header_file_stamp"); cmt_string stamp; if (stamp_macro != 0) { stamp = stamp_macro->resolve_macro_value (); } else if (0 != use) { use->get_full_path (stamp); switch (use->style) { case cmt_style: stamp += CmtSystem::file_separator (); stamp += "cmt"; break; case mgr_style: stamp += CmtSystem::file_separator (); stamp += "mgr"; break; } stamp += CmtSystem::file_separator (); stamp += "cmt_header_file.stamp"; } if (!CmtSystem::test_file (stamp)) continue; //cerr << "1: adding filter: " << package_name << "\n"; cmt_regexp* filter = new cmt_regexp (filter_expr); //cmt_regexp* filter = new cmt_regexp (symbol.resolve_macro_value ()); assert (filter != 0); m_deps_builder.add_header_filter (use, filter, stamp); } } } //-------------------------------------------------- void DependencyGenerator::build (const CmtSystem::cmt_string_vector& arguments) { reset (); // // Parse arguments first // CmtSystem::cmt_string_vector cli_input, all; bool all_sources = false; bool config_files (false); bool start_all (false); for (int i = 0; i < arguments.size (); i++) { cmt_string file_name = arguments[i]; //cerr << "i: " << i << " file_name=" << file_name << endl; if (file_name.substr (0, 5) == "-out=" || file_name.substr (0, 5) == "-out:" || file_name.substr (0, 5) == "/out:" || file_name.substr (0, 5) == "/out=") { file_name.erase (0, 5); m_output_file_name = file_name; } else if (file_name.substr (0, 6) == "-name=" || file_name.substr (0, 6) == "-name:" || file_name.substr (0, 6) == "/name:" || file_name.substr (0, 6) == "/name=") { file_name.erase (0, 6); m_name = file_name; } else if (file_name == "-all_sources" || file_name == "/all_sources") { all_sources = true; } else if (file_name == "-no_stamps" || file_name == "/no_stamps") { m_stamps = false; } else if (file_name.substr (0, 2) == "-I" || file_name.substr (0, 2) == "/I") { file_name.erase (0, 2); //cerr << "include: " << file_name << endl; m_deps_builder.add (file_name, file_name); } else if (file_name == "-start_all" || file_name == "/start_all") { if (start_all) { CmtError::set(CmtError::syntax_error, "Unexpected option " + file_name); return; } start_all = true; } else if (file_name == "-end_all" || file_name == "/end_all") { if (!start_all) { CmtMessage::warning (CmtError::get_error_name (CmtError::syntax_error) + ": Unexpected option " + file_name); } start_all = false; } else if (file_name.substr (0, 1) == "-" #ifdef WIN32 || file_name.substr (0, 1) == "/" #endif ) { if (CmtMessage::active (Verbose)) CmtMessage::warning (CmtError::get_error_name (CmtError::warning) + ": Unknown option " + file_name); } else if (file_name.substr (file_name.size () - 12) == "requirements" || file_name.substr (file_name.size () - 5) == ".make" || file_name.substr (file_name.size () - 3) == ".mk" || file_name.substr (file_name.size () - 6) == ".nmake" || file_name.substr (file_name.size () - 3) == ".in" || file_name.substr (file_name.size () - 6) == ".stamp") { // Configuration changed, // want to rebuild dependencies from scratch if (!config_files) config_files = true; if (!all_sources) all_sources = true; } else if (start_all) { all.push_back (file_name); } else { cli_input.push_back (file_name); } } if (start_all) CmtMessage::warning (CmtError::get_error_name (CmtError::syntax_error) + ": Missing option -end_all"); //cerr << "m_name: " << m_name << endl; /* if (m_name.size () == 0) { CmtError::set(CmtError::syntax_error, "Name missing as first argument"); return; } */ //cerr << "config_files: " << config_files << endl; if (0 != m_name.size ()) m_constituent = Constituent::find (m_name); if (!config_files && 0 == cli_input.size () && 0 == all.size () && 0 == m_constituent) { CmtError::set(CmtError::syntax_error, m_name + ": Files arguments missing"); return; } /* cerr << "cli_input:"; for (int i = 0; i < cli_input.size (); i++) cerr << " " << cli_input[i]; cerr << "\n"; cerr << "all:"; for (int i = 0; i < all.size (); i++) cerr << " " << all[i]; cerr << "\n"; */ prepare_includes (); prepare_header_file_filters (); // // 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 = ".."; m_bin += CmtSystem::file_separator (); m_bin += CmtSystem::getenv ("CMTBIN"); m_bin += CmtSystem::file_separator (); } else if (m_output_file_name != "") { CmtSystem::dirname (m_output_file_name, m_bin); if (m_bin == "") { m_bin = "."; } 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 (); } if (m_output_file_name == "") { m_output_file_name = m_bin; m_output_file_name += m_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"; } } //------------------------------------------------------------------------------- // // For Makefile, we need to select, from cli_input, source files only, // there may be dependencies of source files (typically, header files) as well // cmt_string dependencies; if (!all_sources) { // want to validate cli_input against // either // o all cli sources // or // o m_constituent sources if (int n = set_source_files (all)) { if (0 == validate (cli_input)) { // cli_input contains source files ONLY // calculate dependencies for them ONLY if (CmtSystem::test_file (m_output_file_name)) { if (!dependencies.read (m_output_file_name)) { CmtError::set (CmtError::file_access_error, m_output_file_name); return; } } fill_dependencies (dependencies, cli_input); } else { all_sources = true; // calculate dependencies for // all cli sources // or // m_constituent sources fill_dependencies (dependencies); } } else { // calculate dependencies for all we have fill_dependencies (dependencies, cli_input); } /* if (0 != all.size ()) { // o all cli sources int n_invalid = 0; for (int i = 0; i < cli_input.size (); i++) { bool valid = false; for (int j = 0; j < all.size (); j++) if (cli_input[i] == all[j]) { valid = true; break; } if (!valid) { n_invalid += 1; break; } } if (0 == n_invalid) { // cli_input contains source files ONLY // calculate dependencies for them ONLY if (CmtSystem::test_file (m_output_file_name)) { if (!dependencies.read (m_output_file_name)) { CmtError::set (CmtError::file_access_error, m_output_file_name); return; } } fill_dependencies (dependencies, cli_input); } else { all_sources = true; // calculate dependencies for all (all cli sources) fill_dependencies (dependencies, all); } } else // 0 == all.size () { // set_source_files (); if (int n = set_source_files ()) // if (0 != m_source_files.size ()) { // o m_constituent sources int n_invalid = 0; for (int i = 0; i < cli_input.size (); i++) { bool valid = false; for (int j = 0; j < n; j++) if (cli_input[i] == m_source_files[j].name ()) { valid = true; break; } if (!valid) { n_invalid += 1; break; } } if (0 == n_invalid) { // cli_input contains source files ONLY // calculate dependencies for them ONLY if (CmtSystem::test_file (m_output_file_name)) { if (!dependencies.read (m_output_file_name)) { CmtError::set (CmtError::file_access_error, m_output_file_name); return; } } fill_dependencies (dependencies, cli_input); } else { all_sources = true; // calculate dependencies for m_source_files // (m_constituent sources) fill_dependencies (dependencies); } } else // 0 == m_source_files.size ()) { // no source files to validate against fill_dependencies (dependencies, cli_input); } } */ } else // all_sources = true { if (int n = set_source_files (all)) { // calculate dependencies for m_source_files // either // o all cli sources // or // o m_constituent sources // if any existing fill_dependencies (dependencies); } else { // calculate dependencies for all we have fill_dependencies (dependencies, cli_input); } /* if (0 != all.size ()) { // calculate dependencies for all (all cli sources) fill_dependencies (dependencies, all); } else { if (int n = set_source_files ()) { // calculate dependencies for m_source_files (m_constituent sources) fill_dependencies (dependencies); } else { // calculate dependencies for all we have fill_dependencies (dependencies, cli_input); } } */ } if (CmtError::has_pending_error ()) { if (CmtError::get_last_error_code () == CmtError::path_not_found || CmtError::get_last_error_code () == CmtError::file_access_error || CmtError::get_last_error_code () == CmtError::execution_failed) return; } //------------------------------------------------------------------------------- FILE* f = fopen (m_output_file_name.c_str (), "wb"); if (f != 0) { dependencies.write (f); CmtSystem::close_ostream (f, m_output_file_name); } else { CmtError::set (CmtError::file_access_error, m_output_file_name); } // m_deps_builder.clear (); } //-------------------------------------------------- // o text contains lines with a pattern like : // key = value // o line follows the same pattern // // This function // o if the key found in is found in , removes the first line in with the key, if any // o appends to //-------------------------------------------------- void DependencyGenerator::add_line_to_text (const cmt_string& line, cmt_string& text) const { 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, m_name); if (CmtError::has_pending_error ()) { return line; } // CmtError::set (CmtError::execution_failed, preprocessor, status); // CmtError::set (CmtError::file_access_error, header_file_path); // CmtError::set (CmtError::path_not_found, 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 = m_name; // 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)) { CmtError::set (CmtError::file_access_error, + "Cannot create directory " + stamp_output + " for " + m_name); return line; } 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)) { if (!old_stamp.read (stamp_output)) { CmtError::set (CmtError::file_access_error, stamp_output); return line; } // old_stamp.read (stamp_output); } if (line != old_stamp.substr(0, old_stamp.size () - 1)) { if (!(line + "\n").write (stamp_output)) { CmtError::set (CmtError::file_access_error, stamp_output); return line; } // (line + "\n").write (stamp_output); } } return (line); } //-------------------------------------------------- int DependencyGenerator::fill_dependencies (cmt_string& dependencies) { CmtSystem::cmt_string_vector sources; for (int i = 0; i < m_source_files.size (); i++) { const SourceFile& file = m_source_files[i]; sources.push_back (file.name ()); } return fill_dependencies (dependencies, sources); } //-------------------------------------------------- int DependencyGenerator::fill_dependencies (cmt_string& dependencies, const CmtSystem::cmt_string_vector& sources) { int retval (0); cmt_string file_name; cmt_string compressed_name; for (int i = 0; i < sources.size (); i++) { file_name = sources[i]; //set_full_name (full_name, file_name); CmtSystem::reduce_file_separators (file_name); if (file_name == "") continue; CmtSystem::compress_path (file_name, compressed_name); file_name = compressed_name; //cerr << "file_name: " << file_name << endl; if (file_name == "") continue; const cmt_string& line = build (file_name); if (CmtError::has_pending_error ()) { // if (CmtError::get_last_error_code () == CmtError::file_access_error) return -1; } //cerr << "line: " << line << endl; add_line_to_text (line, dependencies); //cerr << "dependencies: " << dependencies << endl; } return retval; } //-------------------------------------------------- int DependencyGenerator::set_source_files (const CmtSystem::cmt_string_vector& files) { m_source_files.clear (); for (int j = 0; j < files.size (); j++) { const cmt_string& name = files[j]; if (name == "") continue; bool included = false; for (int k = m_source_files.size () - 1; k >= 0; k--) if (m_source_files[k].name () == name) { included = true; break; } if (included) continue; SourceFile& source = m_source_files.add (); source.set (name, Language::null (), ""); } if (m_source_files.size ()) return m_source_files.size (); else return set_source_files (); } //-------------------------------------------------- int DependencyGenerator::set_source_files () { if (0 == m_constituent && 0 != m_name.size ()) m_constituent = Constituent::find (m_name); if (0 == m_constituent) return 0; m_source_files.clear (); const CmtSystem::cmt_string_vector& sources = m_constituent->modules; const cmt_vector& excludes = m_constituent->exclude_exprs; const cmt_vector& selects = m_constituent->select_exprs; cmt_string file_name, full_name; cmt_string compressed_name; cmt_string visited, token; for (int 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 == "") continue; cmt_string suffix; CmtSystem::get_suffix (name, suffix); Language& language = Language::find_with_suffix (suffix); if ((m_constituent->type == Application || m_constituent->type == Library) && language != Language::null () && language.native_dependencies ()) continue; bool included = false; for (int k = m_source_files.size () - 1; k >= 0; k--) if (m_source_files[k].name () == name) { included = true; break; } if (included) continue; SourceFile& source = m_source_files.add (); source.set (name, language, ""); } } return m_source_files.size (); } //-------------------------------------------------- /** * Returns 0, if each file in @files is found in m_source_files, * otherwise returns 1 */ //-------------------------------------------------- int DependencyGenerator::validate (const CmtSystem::cmt_string_vector& files) const { int n_invalid = 0; for (int i = 0; i < files.size (); i++) { bool valid = false; for (int j = 0; j < m_source_files.size (); j++) if (files[i] == m_source_files[j].name ()) { valid = true; break; } if (!valid) { n_invalid += 1; break; } } return n_invalid; }