diff --git a/bin/build_pgms.bat b/bin/build_pgms.bat index 24e347d..5d1a707 100644 --- a/bin/build_pgms.bat +++ b/bin/build_pgms.bat @@ -1,5 +1,5 @@ echo "Use -m32 switch to force 32-bit build" -g++ %* -std=c++11 -DNDEBUG -O2 -o bin/lists.exe src/date.cpp src/issues.cpp src/sections.cpp src/mailing_info.cpp src/report_generator.cpp src/lists.cpp +g++ %* -std=c++11 -DNDEBUG -O2 -o bin/lists.exe src/date.cpp src/issues.cpp src/sections.cpp src/mailing_info.cpp src/report_generator.cpp src/file_names.cpp src/lists.cpp g++ %* -std=c++11 -o bin/section_data.exe src/section_data.cpp g++ %* -std=c++11 -o bin/toc_diff.exe src/toc_diff.cpp g++ %* -std=c++11 -DNDEBUG -O2 -o bin/list_issues.exe src/date.cpp src/issues.cpp src/sections.cpp src/list_issues.cpp diff --git a/bin/build_pgms.sh b/bin/build_pgms.sh index 5ce5968..4758a60 100755 --- a/bin/build_pgms.sh +++ b/bin/build_pgms.sh @@ -1,6 +1,6 @@ #!/bin/sh echo '"Use -m32 switch to force 32-bit build"' -g++ $* -std=c++11 -DNDEBUG -O2 -o bin/lists src/date.cpp src/issues.cpp src/sections.cpp src/mailing_info.cpp src/report_generator.cpp src/lists.cpp +g++ $* -std=c++11 -DNDEBUG -O2 -o bin/lists src/date.cpp src/issues.cpp src/sections.cpp src/mailing_info.cpp src/report_generator.cpp src/file_names.cpp src/lists.cpp g++ $* -std=c++11 -o bin/section_data src/section_data.cpp g++ $* -std=c++11 -o bin/toc_diff src/toc_diff.cpp g++ $* -std=c++11 -DNDEBUG -O2 -o bin/list_issues src/date.cpp src/issues.cpp src/sections.cpp src/list_issues.cpp diff --git a/getting-started.html b/getting-started.html new file mode 100644 index 0000000..238e2fd --- /dev/null +++ b/getting-started.html @@ -0,0 +1,30 @@ + + + + + + + +Codestin Search App + + + + +

Getting Started with Issues List Software

+

 

+

 

+

 

+

Repository organization and workflow

+

A public Git +repository is maintained on the C++ committee's +GitHub account.

+

The +Git Flow +model for repository workflow is at least roughly followed because it works well +and is familiar to many developers. Because this is a simple project, only the +master and develop branches are always active. +Feature branches are used when new features are under development.

+ + + + diff --git a/src/file_names.cpp b/src/file_names.cpp new file mode 100644 index 0000000..9a681fd --- /dev/null +++ b/src/file_names.cpp @@ -0,0 +1,29 @@ +#include "file_names.h" + +namespace lwg { + file_names::file_names(lwg::mailing_info const& config) + { + _active = config.get_attribute("active_name"); + _closed = config.get_attribute("closed_name"); + _defects = config.get_attribute("defects_name"); + _toc = config.get_attribute("toc_name"); + _old_toc = config.get_attribute("old_toc_name"); + _status_index = config.get_attribute("status_index_name"); // not "index_name") to avoid name clash + _status_date_index = config.get_attribute("status_date_index_name"); + _section_index = config.get_attribute("section_index_name"); + _unresolved_toc = config.get_attribute("unresolved_toc_name"); + _unresolved_status_index = config.get_attribute("unresolved_status_index_name"); + _unresolved_status_date_index = config.get_attribute("unresolved_status_date_index_name"); + _unresolved_section_index = config.get_attribute("unresolved_section_index_name"); + _unresolved_prioritized_index = config.get_attribute("unresolved_prioritized_index_name"); + _votable_toc = config.get_attribute("votable_toc_name"); + _votable_status_index = config.get_attribute("votable_status_index_name"); + _votable_status_date_index = config.get_attribute("votable_status_date_index_name"); + _votable_section_index = config.get_attribute("votable_section_index_name"); + _open_index = config.get_attribute("open_index_name"); + _tentative = config.get_attribute("tentative_name"); + _unresolved = config.get_attribute("unresolved_name"); + _immediate = config.get_attribute("immediate_name"); + _issues_for_editor = config.get_attribute("issues_for_editor_name"); + } +} diff --git a/src/file_names.h b/src/file_names.h new file mode 100644 index 0000000..63c06b9 --- /dev/null +++ b/src/file_names.h @@ -0,0 +1,60 @@ +#ifndef INCLUDE_FILE_NAMES_H +#define INCLUDE_FILE_NAMES_H + +#include +#include "mailing_info.h" + +namespace lwg { + + class file_names { + public: + file_names(lwg::mailing_info const& config); + auto active_name() const -> const std::string& {return _active;} + auto closed_name() const -> const std::string& {return _closed;} + auto defects_name() const -> const std::string& {return _defects;} + auto toc_name() const -> const std::string& {return _toc;} + auto old_toc_name() const -> const std::string& {return _old_toc;} + auto status_index_name() const -> const std::string& {return _status_index;} + auto status_date_index_name() const -> const std::string& {return _status_date_index;} + auto section_index_name() const -> const std::string& {return _section_index;} + auto unresolved_toc_name() const -> const std::string& {return _unresolved_toc;} + auto unresolved_status_index_name() const -> const std::string& {return _unresolved_status_index;} + auto unresolved_status_date_index_name() const -> const std::string& {return _unresolved_status_date_index;} + auto unresolved_section_index_name() const -> const std::string& {return _unresolved_section_index;} + auto unresolved_prioritized_index_name() const -> const std::string& {return _unresolved_prioritized_index;} + auto votable_toc_name() const -> const std::string& {return _votable_toc;} + auto votable_status_index_name() const -> const std::string& {return _votable_status_index;} + auto votable_status_date_index_name() const -> const std::string& {return _votable_status_date_index;} + auto votable_section_index_name() const -> const std::string& {return _votable_section_index;} + auto open_index_name() const -> const std::string& {return _open_index ;} + auto tentative_name() const -> const std::string& {return _tentative;} + auto unresolved_name() const -> const std::string& {return _unresolved;} + auto immediate_name() const -> const std::string& {return _immediate;} + auto issues_for_editor_name() const -> const std::string& {return _issues_for_editor;} + private: + std::string _active; + std::string _closed; + std::string _defects; + std::string _toc; + std::string _old_toc; + std::string _status_index; + std::string _status_date_index; + std::string _section_index; + std::string _unresolved_toc; + std::string _unresolved_status_index; + std::string _unresolved_status_date_index; + std::string _unresolved_section_index; + std::string _unresolved_prioritized_index; + std::string _votable_toc; + std::string _votable_status_index; + std::string _votable_status_date_index; + std::string _votable_section_index; + std::string _open_index; + std::string _tentative; + std::string _unresolved; + std::string _immediate; + std::string _issues_for_editor; + }; +} // namespace lwg + +#endif // INCLUDE_FILE_NAMES_H diff --git a/src/issues.cpp b/src/issues.cpp index 3ac07e4..7653a11 100644 --- a/src/issues.cpp +++ b/src/issues.cpp @@ -15,9 +15,9 @@ #include // plan to factor this dependency out namespace { -static constexpr char const * LWG_ACTIVE {"lwg-active.html" }; -static constexpr char const * LWG_CLOSED {"lwg-closed.html" }; -static constexpr char const * LWG_DEFECTS{"lwg-defects.html"}; + char const * LWG_ACTIVE; + char const * LWG_CLOSED; + char const * LWG_DEFECTS; // date utilites may factor out again auto parse_month(std::string const & m) -> gregorian::month { @@ -68,6 +68,12 @@ auto report_date_file_last_modified(std::string const & filename) -> gregorian:: } // close unnamed namespace +void lwg::initialize_issues(file_names const & names) { + LWG_ACTIVE = names.active_name().c_str(); + LWG_CLOSED = names.closed_name().c_str(); + LWG_DEFECTS = names.defects_name().c_str(); +} + // functions to relate the status of an issue to its relevant published list document auto lwg::filename_for_status(std::string stat) -> std::string { // Tentative issues are always active diff --git a/src/issues.h b/src/issues.h index 0c43475..e81ecc8 100644 --- a/src/issues.h +++ b/src/issues.h @@ -9,10 +9,13 @@ // solution specific headers #include "date.h" +#include "file_names.h" namespace lwg { +void initialize_issues(file_names const & names); + using section_tag = std::string; struct issue { diff --git a/src/list_issues.cpp b/src/list_issues.cpp index a865346..0e721e9 100644 --- a/src/list_issues.cpp +++ b/src/list_issues.cpp @@ -1,5 +1,5 @@ // This program reads all the issues in the issues directory passed as the first command line argument. -// If all documents are successfully parsed, it will generate the standard LWG Issues List documents +// If all documents are successfully parsed, it will generate the standard Issues List documents // for an ISO SC22 WG21 mailing. // Based on code originally donated by Howard Hinnant @@ -110,7 +110,7 @@ auto read_file_into_string(std::string const & filename) -> std::string { void filter_issues(std::string const & issues_path, lwg::section_map & section_db, std::function predicate) { // Open the specified directory, 'issues_path', and iterate all the '.xml' files - // it contains, parsing each such file as an LWG issue document. Write to 'out' + // it contains, parsing each such file as an issue document. Write to 'out' // the number of every issue that satisfies the 'predicate'. // // The current implementation relies directly on POSIX headers, but the preferred diff --git a/src/lists.cpp b/src/lists.cpp index d6b5d29..7755297 100644 --- a/src/lists.cpp +++ b/src/lists.cpp @@ -1,5 +1,5 @@ // This program reads all the issues in the issues directory passed as the first command line argument. -// If all documents are successfully parsed, it will generate the standard LWG Issues List documents +// If all documents are successfully parsed, it will generate the standard Issues List documents // for an ISO SC22 WG21 mailing. // Based on code originally donated by Howard Hinnant @@ -33,7 +33,7 @@ // string_view // Its coding style assumes a standard library optimized with move-semantics -// The only known compiler to support all of this today is the experimental gcc trunk (4.6) +// The only known compiler to support all of this today is the experimental gcc trunk (4.9) // TODO // . Better handling of TR "sections", and grouping of issues in "Clause X" @@ -82,6 +82,7 @@ #include "mailing_info.h" #include "report_generator.h" #include "sections.h" +#include "file_names.h" #if 0 @@ -110,7 +111,7 @@ auto read_file_into_string(std::string const & filename) -> std::string { if (!infile.is_open()) { throw std::runtime_error{"Unable to open file " + filename}; } - + else std::cout << "Reading file " + filename << std::endl; std::istreambuf_iterator first{infile}, last{}; return std::string {first, last}; } @@ -120,7 +121,7 @@ auto read_file_into_string(std::string const & filename) -> std::string { auto read_issues(std::string const & issues_path, lwg::section_map & section_db) -> std::vector { // Open the specified directory, 'issues_path', and iterate all the '.xml' files - // it contains, parsing each such file as an LWG issue document. Return the set + // it contains, parsing each such file as an issue document. Return the set // of issues as a vector. // // The current implementation relies directly on POSIX headers, but the preferred @@ -679,7 +680,7 @@ void check_is_directory(std::string const & directory) { int main(int argc, char* argv[]) { try { std::string path; - std::cout << "Preparing new LWG issues lists..." << std::endl; + std::cout << "Preparing new issues lists..." << std::endl; if (argc == 2) { path = argv[1]; } @@ -718,13 +719,11 @@ int main(int argc, char* argv[]) { std::cout << temp << ' ' << elem.second << '\n'; } #endif - - auto const old_issues = read_issues_from_toc(read_file_into_string(path + "meta-data/lwg-toc.old.html")); auto const issues_path = path + "xml/"; - lwg::mailing_info lwg_issues_xml = [&issues_path](){ - std::string filename{issues_path + "lwg-issues.xml"}; + lwg::mailing_info config = [&issues_path](){ + std::string filename{issues_path + "config.xml"}; std::ifstream infile{filename}; if (!infile.is_open()) { throw std::runtime_error{"Unable to open " + filename}; @@ -733,15 +732,20 @@ int main(int argc, char* argv[]) { return lwg::mailing_info{infile}; }(); - //lwg::mailing_info lwg_issues_xml{issues_path}; + //lwg::mailing_info config{issues_path}; + lwg::file_names names(config); + lwg::initialize_issues(names); + + auto const old_issues = read_issues_from_toc(read_file_into_string( + path + "meta-data/" + names.old_toc_name())); std::cout << "Reading issues from: " << issues_path << std::endl; auto issues = read_issues(issues_path, section_db); prepare_issues(issues, section_db); - lwg::report_generator generator{lwg_issues_xml, section_db}; + lwg::report_generator generator{config, section_db, names}; // issues must be sorted by number before making the mailing list documents @@ -783,32 +787,32 @@ int main(int argc, char* argv[]) { // Now we have a parsed and formatted set of issues, we can write the standard set of HTML documents // Note that each of these functions is going to re-sort the 'issues' vector for its own purposes - generator.make_sort_by_num (issues, {target_path + "lwg-toc.html"}); - generator.make_sort_by_status (issues, {target_path + "lwg-status.html"}); - generator.make_sort_by_status_mod_date(issues, {target_path + "lwg-status-date.html"}); // this report is useless, as git checkouts touch filestamps - generator.make_sort_by_section (issues, {target_path + "lwg-index.html"}); + generator.make_sort_by_num (issues, {target_path + names.toc_name()}); + generator.make_sort_by_status (issues, {target_path + names.status_index_name()}); + generator.make_sort_by_status_mod_date(issues, {target_path + names.status_date_index_name()}); // this report is useless, as git checkouts touch filestamps + generator.make_sort_by_section (issues, {target_path + names.status_index_name()}); - // Note that this additional document is very similar to unresolved-index.html below - generator.make_sort_by_section (issues, {target_path + "lwg-index-open.html"}, true); + // Note that this additional document is very similar to unresolved-section-index below + generator.make_sort_by_section (issues, {target_path + names.open_index_name()}, true); // Make a similar set of index documents for the issues that are 'live' during a meeting - // Note that these documents want to reference each other, rather than lwg- equivalents, + // Note that these documents want to reference each other, rather than unfiltered equivalents, // although it may not be worth attempting fix-ups as the per-issue level // During meetings, it would be good to list newly-Ready issues here - generator.make_sort_by_num (unresolved_issues, {target_path + "unresolved-toc.html"}); - generator.make_sort_by_status (unresolved_issues, {target_path + "unresolved-status.html"}); - generator.make_sort_by_status_mod_date(unresolved_issues, {target_path + "unresolved-status-date.html"}); - generator.make_sort_by_section (unresolved_issues, {target_path + "unresolved-index.html"}); - generator.make_sort_by_priority (unresolved_issues, {target_path + "unresolved-prioritized.html"}); + generator.make_sort_by_num (unresolved_issues, {target_path + names.unresolved_toc_name()}); + generator.make_sort_by_status (unresolved_issues, {target_path + names.unresolved_status_index_name()}); + generator.make_sort_by_status_mod_date(unresolved_issues, {target_path + names.unresolved_status_date_index_name()}); + generator.make_sort_by_section (unresolved_issues, {target_path + names.unresolved_section_index_name()}); + generator.make_sort_by_priority (unresolved_issues, {target_path + names.unresolved_prioritized_index_name()}); // Make another set of index documents for the issues that are up for a vote during a meeting - // Note that these documents want to reference each other, rather than lwg- equivalents, + // Note that these documents want to reference each other, rather than unfiltered equivalents, // although it may not be worth attempting fix-ups as the per-issue level // Between meetings, it would be good to list Ready issues here - generator.make_sort_by_num (votable_issues, {target_path + "votable-toc.html"}); - generator.make_sort_by_status (votable_issues, {target_path + "votable-status.html"}); - generator.make_sort_by_status_mod_date(votable_issues, {target_path + "votable-status-date.html"}); - generator.make_sort_by_section (votable_issues, {target_path + "votable-index.html"}); + generator.make_sort_by_num (votable_issues, {target_path + names.votable_toc_name()}); + generator.make_sort_by_status (votable_issues, {target_path + names.votable_status_index_name()}); + generator.make_sort_by_status_mod_date(votable_issues, {target_path + names.votable_status_date_index_name()}); + generator.make_sort_by_section (votable_issues, {target_path + names.votable_section_index_name()}); std::cout << "Made all documents\n"; } diff --git a/src/mailing_info.cpp b/src/mailing_info.cpp index f93fba2..108bf92 100644 --- a/src/mailing_info.cpp +++ b/src/mailing_info.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace { @@ -12,7 +13,7 @@ void replace_all_irefs(std::vector const & issues, std::string & s) // Replace all tagged "issues references" in string 's' with an HTML anchor-link to the live issue // in its appropriate issue list, as determined by the issue's status. // Format of an issue reference: - // Format of anchor: ISS + // Format of anchor: ISS for (auto i = s.find("', i); @@ -73,7 +74,27 @@ namespace lwg mailing_info::mailing_info(std::istream & stream) : m_data{std::istreambuf_iterator{stream}, std::istreambuf_iterator{}} - { +{ + // replace all text in the form: + // + // with the attribute-value for that attribute-name + + std::string::size_type first, last, pos = 0; + while ((first = m_data.find("", first + 10); + if (last == std::string::npos) + { + std::string msg{std::string{"error in config.xml: failed to find close for: "} + + m_data.substr(first, first + 32).c_str() + "... "}; + throw std::runtime_error{msg.c_str()}; + return; + } + //std::cout << "***attribute-name is " << m_data.substr(first+10, last-(first+10)) << std::endl; + //std::cout << " attribute-value is " << get_attribute(m_data.substr(first+10, last-(first+10))) << std::endl; + m_data.replace(first, last+3-first, get_attribute(m_data.substr(first+10, last-(first+10)))); + pos = last; + } } auto mailing_info::get_doc_number(std::string doc) const -> std::string { @@ -93,6 +114,16 @@ auto mailing_info::get_doc_number(std::string doc) const -> std::string { return get_attribute(doc); } +auto mailing_info::get_doc_name() const -> std::string +{ + return get_attribute("doc_name"); +} + +auto mailing_info::get_doc_reference() const -> std::string +{ + return get_attribute("doc_reference"); +} + auto mailing_info::get_intro(std::string doc) const -> std::string { if (doc == "active") { doc = ""; @@ -109,12 +140,12 @@ auto mailing_info::get_intro(std::string doc) const -> std::string { auto i = m_data.find(doc); if (i == std::string::npos) { - throw std::runtime_error{"Unable to find intro in lwg-issues.xml"}; + throw std::runtime_error{"Unable to find intro in config.xml"}; } i += doc.size(); auto j = m_data.find("", i); if (j == std::string::npos) { - throw std::runtime_error{"Unable to parse intro in lwg-issues.xml"}; + throw std::runtime_error{"Unable to parse intro in config.xml"}; } return m_data.substr(i, j-i); } @@ -124,12 +155,12 @@ auto mailing_info::get_maintainer() const -> std::string { std::string r = get_attribute("maintainer"); auto m = r.find("<"); if (m == std::string::npos) { - throw std::runtime_error{"Unable to parse maintainer email address in lwg-issues.xml"}; + throw std::runtime_error{"Unable to parse maintainer email address in config.xml"}; } m += sizeof("<") - 1; auto me = r.find(">", m); if (me == std::string::npos) { - throw std::runtime_error{"Unable to parse maintainer email address in lwg-issues.xml"}; + throw std::runtime_error{"Unable to parse maintainer email address in config.xml"}; } std::string email = r.substr(m, me-m); // < lwgchair@gmail.com > @@ -146,13 +177,13 @@ auto mailing_info::get_revision() const -> std::string { auto mailing_info::get_revisions(std::vector const & issues, std::string const & diff_report) const -> std::string { auto i = m_data.find(""); if (i == std::string::npos) { - throw std::runtime_error{"Unable to find in lwg-issues.xml"}; + throw std::runtime_error{"Unable to find in config.xml"}; } i += sizeof("") - 1; auto j = m_data.find("", i); if (j == std::string::npos) { - throw std::runtime_error{"Unable to find in lwg-issues.xml"}; + throw std::runtime_error{"Unable to find in config.xml"}; } auto s = m_data.substr(i, j-i); j = 0; @@ -193,13 +224,13 @@ auto mailing_info::get_revisions(std::vector const & issues, std::string auto mailing_info::get_statuses() const -> std::string { auto i = m_data.find(""); if (i == std::string::npos) { - throw std::runtime_error{"Unable to find statuses in lwg-issues.xml"}; + throw std::runtime_error{"Unable to find statuses in config.xml"}; } i += sizeof("") - 1; auto j = m_data.find("", i); if (j == std::string::npos) { - throw std::runtime_error{"Unable to parse statuses in lwg-issues.xml"}; + throw std::runtime_error{"Unable to parse statuses in config.xml"}; } return m_data.substr(i, j-i); } @@ -209,12 +240,12 @@ auto mailing_info::get_attribute(std::string const & attribute_name) const -> st std::string search_string{attribute_name + "=\""}; auto i = m_data.find(search_string); if (i == std::string::npos) { - throw std::runtime_error{"Unable to find " + attribute_name + " in lwg-issues.xml"}; + throw std::runtime_error{"Unable to find " + attribute_name + " in config.xml"}; } i += search_string.size(); auto j = m_data.find('\"', i); if (j == std::string::npos) { - throw std::runtime_error{"Unable to parse " + attribute_name + " in lwg-issues.xml"}; + throw std::runtime_error{"Unable to parse " + attribute_name + " in config.xml"}; } return m_data.substr(i, j-i); } diff --git a/src/mailing_info.h b/src/mailing_info.h index 54342c9..f68afbc 100644 --- a/src/mailing_info.h +++ b/src/mailing_info.h @@ -19,13 +19,15 @@ struct mailing_info { auto get_revision() const -> std::string; auto get_revisions(std::vector const & issues, std::string const & diff_report) const -> std::string; auto get_statuses() const -> std::string; + auto get_doc_name() const -> std::string; // Examples: "C++ Standard Library" or "File System Technical Specification" + auto get_doc_reference() const -> std::string; // Examples: "ISO/IEC IS 14882:2011(E)" or "ISO/IEC TS 18822" -private: auto get_attribute(std::string const & attribute_name) const -> std::string; // Return the value of the first xml attibute having the specified 'attribute_name' // in the stored XML string, 'm_data', without regard to which element holds that // attribute. +private: std::string m_data; // 'm_data' is reparsed too many times in practice, and memory use is not a major concern. // Should cache each of the reproducible calls in additional member strings, either at diff --git a/src/report_generator.cpp b/src/report_generator.cpp index 69e36de..afec2ca 100644 --- a/src/report_generator.cpp +++ b/src/report_generator.cpp @@ -126,9 +126,9 @@ auto major_section(lwg::section_num const & sn) -> std::string { } auto remove_square_brackets(lwg::section_tag const & tag) -> lwg::section_tag { - assert(tag.size() > 2); - assert(tag.front() == '['); - assert(tag.back() == ']'); + //assert(tag.size() > 2); + //assert(tag.front() == '['); + //assert(tag.back() == ']'); return tag.substr(1, tag.size()-2); } @@ -186,7 +186,8 @@ void print_file_trailer(std::ostream& out) { } -void print_table(std::ostream& out, std::vector::const_iterator i, std::vector::const_iterator e, lwg::section_map & section_db) { +void print_table(std::ostream& out, std::vector::const_iterator i, std::vector::const_iterator e, + lwg::section_map & section_db, lwg::file_names const & names) { #if defined (DEBUG_LOGGING) std::cout << "\t" << std::distance(i,e) << " items to add to table" << std::endl; #endif @@ -194,12 +195,12 @@ void print_table(std::ostream& out, std::vector::const_iterator i, s out << R"( - - - + + + - + )"; @@ -212,7 +213,8 @@ R"(
IssueStatusSectionIssueStatusSection Title Proposed ResolutionPriorityPriority Duplicates
out << "\n"; // Status - out << "\n"; + out << "\n"; // Section out << "
" << make_html_anchor(*i) << "stat) << "\">" << i->stat << "num << "\">stat) << "\">" + << i->stat << "num << "\">"; @@ -254,7 +256,8 @@ assert(!i->tags.empty()); } template -void print_issues(std::ostream & out, std::vector const & issues, lwg::section_map & section_db, Pred pred) { +void print_issues(std::ostream & out, std::vector const & issues, lwg::section_map & section_db, + lwg::file_names const & names, Pred pred) { std::multiset const all_issues{ issues.begin(), issues.end()} ; std::multiset const issues_by_status{ issues.begin(), issues.end() }; @@ -279,7 +282,8 @@ void print_issues(std::ostream & out, std::vector const & issues, lw out << ", " << section_db[iss.tags[k]] << " " << iss.tags[k]; } - out << " Status: " << iss.stat << "\n"; + out << " Status: " + << iss.stat << "\n"; out << " Submitter: " << iss.submitter << " Opened: "; print_date(out, iss.date); @@ -289,16 +293,19 @@ void print_issues(std::ostream & out, std::vector const & issues, lw // view active issues in [] if (active_issues.count(iss) > 1) { - out << "

View other active issues in " << iss.tags[0] << ".

\n"; + out << "

View other active issues in " << iss.tags[0] << ".

\n"; } // view all issues in [] if (all_issues.count(iss) > 1) { - out << "

View all other issues in " << iss.tags[0] << ".

\n"; + out << "

View all other issues in " << iss.tags[0] << ".

\n"; } // view all issues with same status if (issues_by_status.count(iss) > 1) { - out << "

View all issues with " << iss.stat << " status.

\n"; + out << "

View all issues with " + << iss.stat << " status.

\n"; } // duplicates @@ -340,12 +347,12 @@ void print_resolutions(std::ostream & out, std::vector const & issue } } -void print_paper_heading(std::ostream& out, std::string const & paper, lwg::mailing_info const & lwg_issues_xml) { +void print_paper_heading(std::ostream& out, std::string const & paper, lwg::mailing_info const & config) { out << R"( - + @@ -357,22 +364,22 @@ R"(
Doc. no.)" << lwg_issues_xml.get_doc_number(paper) << R"()" << config.get_doc_number(paper) << R"(
Date:
- +
Reply to:)" << lwg_issues_xml.get_maintainer() << R"()" << config.get_maintainer() << R"(
)"; out << "

"; if (paper == "active") { - out << "C++ Standard Library Active Issues List (Revision "; + out << config.get_doc_name() + " Active Issues List (Revision "; } else if (paper == "defect") { - out << "C++ Standard Library Defect Report List (Revision "; + out << config.get_doc_name() + " Defect Report List (Revision "; } else if (paper == "closed") { - out << "C++ Standard Library Closed Issues List (Revision "; + out << config.get_doc_name() + " Closed Issues List (Revision "; } - out << lwg_issues_xml.get_revision() << ")

\n"; + out << config.get_revision() << ")\n"; out << "

" << build_timestamp << "

"; } @@ -388,17 +395,17 @@ namespace lwg void report_generator::make_active(std::vector const & issues, std::string const & path, std::string const & diff_report) { assert(std::is_sorted(issues.begin(), issues.end(), order_by_issue_number{})); - std::string filename{path + "lwg-active.html"}; + std::string filename{path + names.active_name()}; std::ofstream out{filename.c_str()}; if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "C++ Standard Library Active Issues List"); - print_paper_heading(out, "active", lwg_issues_xml); - out << lwg_issues_xml.get_intro("active") << '\n'; - out << "

Revision History

\n" << lwg_issues_xml.get_revisions(issues, diff_report) << '\n'; - out << "

Issue Status

\n" << lwg_issues_xml.get_statuses() << '\n'; + print_file_header(out, "Active Issues List"); + print_paper_heading(out, "active", config); + out << config.get_intro("active") << '\n'; + out << "

Revision History

\n" << config.get_revisions(issues, diff_report) << '\n'; + out << "

Issue Status

\n" << config.get_statuses() << '\n'; out << "

Active Issues

\n"; - print_issues(out, issues, section_db, [](issue const & i) {return is_active(i.stat);} ); + print_issues(out, issues, section_db, names, [](issue const & i) {return is_active(i.stat);} ); print_file_trailer(out); } @@ -406,16 +413,16 @@ void report_generator::make_active(std::vector const & issues, std::strin void report_generator::make_defect(std::vector const & issues, std::string const & path, std::string const & diff_report) { assert(std::is_sorted(issues.begin(), issues.end(), order_by_issue_number{})); - std::string filename{path + "lwg-defects.html"}; + std::string filename{path + names.defects_name()}; std::ofstream out(filename.c_str()); if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "C++ Standard Library Defect Report List"); - print_paper_heading(out, "defect", lwg_issues_xml); - out << lwg_issues_xml.get_intro("defect") << '\n'; - out << "

Revision History

\n" << lwg_issues_xml.get_revisions(issues, diff_report) << '\n'; + print_file_header(out, "Defect Report List"); + print_paper_heading(out, "defect", config); + out << config.get_intro("defect") << '\n'; + out << "

Revision History

\n" << config.get_revisions(issues, diff_report) << '\n'; out << "

Defect Reports

\n"; - print_issues(out, issues, section_db, [](issue const & i) {return is_defect(i.stat);} ); + print_issues(out, issues, section_db, names, [](issue const & i) {return is_defect(i.stat);} ); print_file_trailer(out); } @@ -423,37 +430,37 @@ void report_generator::make_defect(std::vector const & issues, std::strin void report_generator::make_closed(std::vector const & issues, std::string const & path, std::string const & diff_report) { assert(std::is_sorted(issues.begin(), issues.end(), order_by_issue_number{})); - std::string filename{path + "lwg-closed.html"}; + std::string filename{path + names.closed_name()}; std::ofstream out{filename.c_str()}; if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "C++ Standard Library Closed Issues List"); - print_paper_heading(out, "closed", lwg_issues_xml); - out << lwg_issues_xml.get_intro("closed") << '\n'; - out << "

Revision History

\n" << lwg_issues_xml.get_revisions(issues, diff_report) << '\n'; + print_file_header(out, "Closed Issues List"); + print_paper_heading(out, "closed", config); + out << config.get_intro("closed") << '\n'; + out << "

Revision History

\n" << config.get_revisions(issues, diff_report) << '\n'; out << "

Closed Issues

\n"; - print_issues(out, issues, section_db, [](issue const & i) {return is_closed(i.stat);} ); + print_issues(out, issues, section_db, names, [](issue const & i) {return is_closed(i.stat);} ); print_file_trailer(out); } -// Additional non-standard documents, useful for running LWG meetings +// Additional non-standard documents, useful for running meetings void report_generator::make_tentative(std::vector const & issues, std::string const & path) { // publish a document listing all tentative issues that may be acted on during a meeting. assert(std::is_sorted(issues.begin(), issues.end(), order_by_issue_number{})); - std::string filename{path + "lwg-tentative.html"}; + std::string filename{path + names.tentative_name()}; std::ofstream out{filename.c_str()}; if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "C++ Standard Library Tentative Issues"); -// print_paper_heading(out, "active", lwg_issues_xml); -// out << lwg_issues_xml.get_intro("active") << '\n'; -// out << "

Revision History

\n" << lwg_issues_xml.get_revisions(issues) << '\n'; -// out << "

Issue Status

\n" << lwg_issues_xml.get_statuses() << '\n'; + print_file_header(out, "Tentative Issues"); +// print_paper_heading(out, "active", config); +// out << config.get_intro("active") << '\n'; +// out << "

Revision History

\n" << config.get_revisions(issues) << '\n'; +// out << "

Issue Status

\n" << config.get_statuses() << '\n'; out << "

" << build_timestamp << "

"; out << "

Tentative Issues

\n"; - print_issues(out, issues, section_db, [](issue const & i) {return is_tentative(i.stat);} ); + print_issues(out, issues, section_db, names, [](issue const & i) {return is_tentative(i.stat);} ); print_file_trailer(out); } @@ -462,18 +469,18 @@ void report_generator::make_unresolved(std::vector const & issues, std::s // publish a document listing all non-tentative, non-ready issues that must be reviewed during a meeting. assert(std::is_sorted(issues.begin(), issues.end(), order_by_issue_number{})); - std::string filename{path + "lwg-unresolved.html"}; + std::string filename{path + names.unresolved_name()}; std::ofstream out{filename.c_str()}; if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "C++ Standard Library Unresolved Issues"); -// print_paper_heading(out, "active", lwg_issues_xml); -// out << lwg_issues_xml.get_intro("active") << '\n'; -// out << "

Revision History

\n" << lwg_issues_xml.get_revisions(issues) << '\n'; -// out << "

Issue Status

\n" << lwg_issues_xml.get_statuses() << '\n'; + print_file_header(out, "Unresolved Issues"); +// print_paper_heading(out, "active", config); +// out << config.get_intro("active") << '\n'; +// out << "

Revision History

\n" << config.get_revisions(issues) << '\n'; +// out << "

Issue Status

\n" << config.get_statuses() << '\n'; out << "

" << build_timestamp << "

"; out << "

Unresolved Issues

\n"; - print_issues(out, issues, section_db, [](issue const & i) {return is_not_resolved(i.stat);} ); + print_issues(out, issues, section_db, names, [](issue const & i) {return is_not_resolved(i.stat);} ); print_file_trailer(out); } @@ -481,12 +488,12 @@ void report_generator::make_immediate(std::vector const & issues, std::st // publish a document listing all non-tentative, non-ready issues that must be reviewed during a meeting. assert(std::is_sorted(issues.begin(), issues.end(), order_by_issue_number{})); - std::string filename{path + "lwg-immediate.html"}; + std::string filename{path + names.unresolved_name()}; std::ofstream out{filename.c_str()}; if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "C++ Standard Library Issues Resolved Directly In [INSERT CURRENT MEETING HERE]"); -out << R"(

C++ Standard Library Issues Resolved Directly In [INSERT CURRENT MEETING HERE]

+ print_file_header(out, "Issues Resolved Directly"); + out << R"(

)" << config.get_doc_name() << R"( Issues Resolved Directly In [INSERT CURRENT MEETING HERE]

@@ -507,7 +514,7 @@ out << R"(

C++ Standard Library Issues Resolved Directly In [INSERT CURRENT M

Doc. no.
)"; out << "

Immediate Issues

\n"; - print_issues(out, issues, section_db, [](issue const & i) {return "Immediate" == i.stat;} ); + print_issues(out, issues, section_db, names, [](issue const & i) {return "Immediate" == i.stat;} ); print_file_trailer(out); } @@ -515,13 +522,13 @@ void report_generator::make_editors_issues(std::vector const & issues, st // publish a single document listing all 'Voting' and 'Immediate' resolutions (only). assert(std::is_sorted(issues.begin(), issues.end(), order_by_issue_number{})); - std::string filename{path + "lwg-issues-for-editor.html"}; + std::string filename{path + names.issues_for_editor_name()}; std::ofstream out{filename.c_str()}; if (!out) { throw std::runtime_error{"Failed to open " + filename}; } - print_file_header(out, "C++ Standard Library Issues Resolved Directly In [INSERT CURRENT MEETING HERE]"); - out << "

C++ Standard Library Issues Resolved In [INSERT CURRENT MEETING HERE]

\n"; + print_file_header(out, "Issues Resolved Directly"); + out << "

" << config.get_doc_name() << " Resolved In [INSERT CURRENT MEETING HERE]

\n"; print_resolutions(out, issues, section_db, [](issue const & i) {return "Pending WP" == i.stat;} ); print_file_trailer(out); } @@ -532,18 +539,19 @@ void report_generator::make_sort_by_num(std::vector& issues, std::string std::ofstream out{filename.c_str()}; if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "LWG Table of Contents"); + print_file_header(out, "Table of Contents"); - out << -R"(

C++ Standard Library Issues List (Revision )" << lwg_issues_xml.get_revision() << R"()

+ out << "

" << config.get_doc_name() << +R"( Issues List (Revision )" << config.get_revision() << R"()

Table of Contents

-

Reference ISO/IEC IS 14882:2011(E)

-

This document is the Table of Contents for the Library Active Issues List, -Library Defect Reports List, and Library Closed Issues List.

+

Reference )" << config.get_doc_reference() << R"(

+

This document is the Table of Contents for the Active Issues List, +Defect Reports List, +and Closed Issues List.

)"; out << "

" << build_timestamp << "

"; - print_table(out, issues.begin(), issues.end(), section_db); + print_table(out, issues.begin(), issues.end(), section_db, names); print_file_trailer(out); } @@ -554,18 +562,19 @@ void report_generator::make_sort_by_priority(std::vector& issues, std::st std::ofstream out{filename.c_str()}; if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "LWG Table of Contents"); - - out << -R"(

C++ Standard Library Issues List (Revision )" << lwg_issues_xml.get_revision() << R"()

-

Table of Contents

-

Reference ISO/IEC IS 14882:2011(E)

-

This document is the Table of Contents for the Library Active Issues List, -Library Defect Reports List, and Library Closed Issues List.

+ print_file_header(out, "Table of Contents"); + + out << "

" << config.get_doc_name() << +R"( Issues List (Revision )" << config.get_revision() << R"()

+

Index by Issue Number

+

Reference )" << config.get_doc_reference() << R"(

+

This document is the Table of Contents for the Active Issues List, +Defect Reports List, +and Closed Issues List.

)"; out << "

" << build_timestamp << "

"; -// print_table(out, issues.begin(), issues.end(), section_db); +// print_table(out, issues.begin(), issues.end(), section_db, names); for (auto i = issues.cbegin(), e = issues.cend(); i != e;) { int px = i->priority; @@ -578,7 +587,7 @@ R"(

C++ Standard Library Issues List (Revision )" << lwg_issues_xml.get_revis out << "Priority " << px; } out << " (" << (j-i) << " issues)

\n"; - print_table(out, i, j, section_db); + print_table(out, i, j, section_db, names); i = j; } @@ -595,15 +604,16 @@ void report_generator::make_sort_by_status(std::vector& issues, std::stri std::ofstream out{filename.c_str()}; if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "LWG Index by Status and Section"); + print_file_header(out, "Status and Section Index"); - out << -R"(

C++ Standard Library Issues List (Revision )" << lwg_issues_xml.get_revision() << R"()

+ out << "

" << config.get_doc_name() << +R"( Issues List (Revision )" << config.get_revision() << R"()

Index by Status and Section

-

Reference ISO/IEC IS 14882:2011(E)

+

Reference )" << config.get_doc_reference() << R"(

-This document is the Index by Status and Section for the Library Active Issues List, -Library Defect Reports List, and Library Closed Issues List. +This document is the Index by Status and Section for the Active Issues List, +Defect Reports List, +and Closed Issues List.

)"; @@ -613,7 +623,7 @@ This document is the Index by Status and Section for the " << current_status << " (" << (j-i) << " issues)\n"; - print_table(out, i, j, section_db); + print_table(out, i, j, section_db, names); i = j; } @@ -630,15 +640,16 @@ void report_generator::make_sort_by_status_mod_date(std::vector & issues, std::ofstream out{filename.c_str()}; if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "LWG Index by Status and Date"); + print_file_header(out, "Status and Date Index"); - out << -R"(

C++ Standard Library Issues List (Revision )" << lwg_issues_xml.get_revision() << R"()

+ out << "

" << config.get_doc_name() << +R"( Issues List (Revision )" << config.get_revision() << R"()

Index by Status and Date

-

Reference ISO/IEC IS 14882:2011(E)

+

Reference )" << config.get_doc_reference() << R"(

-This document is the Index by Status and Date for the Library Active Issues List, -Library Defect Reports List, and Library Closed Issues List. +This document is the Index by Status and Date for the Active Issues List, +Defect Reports List, +and Closed Issues List.

)"; out << "

" << build_timestamp << "

"; @@ -647,7 +658,7 @@ This document is the Index by Status and Date for the std::string const & current_status = i->stat; auto j = find_if(i, e, [&](issue const & iss){ return iss.stat != current_status; } ); out << "

" << current_status << " (" << (j-i) << " issues)

\n"; - print_table(out, i, j, section_db); + print_table(out, i, j, section_db, names); i = j; } @@ -680,14 +691,15 @@ void report_generator::make_sort_by_section(std::vector& issues, std::str std::ofstream out(filename.c_str()); if (!out) throw std::runtime_error{"Failed to open " + filename}; - print_file_header(out, "LWG Index by Section"); + print_file_header(out, "Section Index" ); - out << "

C++ Standard Library Issues List (Revision " << lwg_issues_xml.get_revision() << ")

\n"; + out << "

" << config.get_doc_name() << " Issues List (Revision " << config.get_revision() << ")

\n"; out << "

Index by Section

\n"; - out << "

Reference ISO/IEC IS 14882:2011(E)

\n"; - out << "

This document is the Index by Section for the Library Active Issues List"; + out << "

Reference " << config.get_doc_reference() << "

\n"; + out << "

This document is the Index by Section for the Library Active Issues List"; if(!active_only) { - out << ", Library Defect Reports List, and Library Closed Issues List"; + out << ", Library Defect Reports List," + " and Library Closed Issues List"; } out << ".

\n"; out << "

Index by Section"; @@ -696,10 +708,10 @@ void report_generator::make_sort_by_section(std::vector& issues, std::str } out << "

\n"; if (active_only) { - out << "

(view all issues)

\n"; + out << "

(view all issues)

\n"; } else { - out << "

(view only non-Ready open issues)

\n"; + out << "

(view only non-Ready open issues)

\n"; } out << "

" << build_timestamp << "

"; @@ -716,13 +728,13 @@ assert(!i->tags.empty()); std::string const msn{major_section(section_db[i->tags[0]])}; out << "

" << "Section " << msn << " (" << (j-i) << " issues)

\n"; if (active_only) { - out << "

(view all issues)

\n"; + out << "

(view all issues)

\n"; } else if (mjr_section_open.count(*i) > 0) { - out << "

(view only non-Ready open issues)

\n"; + out << "

(view only non-Ready open issues)

\n"; } - print_table(out, i, j, section_db); + print_table(out, i, j, section_db, names); i = j; } diff --git a/src/report_generator.h b/src/report_generator.h index 5ce6819..33088e3 100644 --- a/src/report_generator.h +++ b/src/report_generator.h @@ -5,6 +5,7 @@ #include #include "issues.h" // cannot forward declare the 'section_map' alias, nor the 'LwgIssuesXml' alias +#include "file_names.h" namespace lwg { @@ -14,9 +15,10 @@ struct mailing_info; struct report_generator { - report_generator(mailing_info const & info, section_map & sections) - : lwg_issues_xml(info) + report_generator(mailing_info const & info, section_map & sections, file_names const & names_) + : config(info) , section_db(sections) + , names(names_) { } @@ -30,7 +32,7 @@ struct report_generator { void make_closed(std::vector const & issues, std::string const & path, std::string const & diff_report); - // Additional non-standard documents, useful for running LWG meetings + // Additional non-standard documents, useful for running meetings void make_tentative(std::vector const & issues, std::string const & path); // publish a document listing all tentative issues that may be acted on during a meeting. @@ -55,8 +57,9 @@ struct report_generator { void make_editors_issues(std::vector const & issues, std::string const & path); private: - mailing_info const & lwg_issues_xml; + mailing_info const & config; section_map & section_db; + file_names const & names; }; } // close namespace lwg